2013-04-12 44 views
9

Tôi muốn tạo một ứng dụng web cho phép người dùng tải hình ảnh của họ lên máy chủ. Khi họ nhấp gửi, hình ảnh của họ sẽ được tải lên máy chủ (nhiều phần). Trước khi lưu, tôi muốn thực hiện một số hoạt động với hình ảnh, vì vậy tôi quyết định sử dụng ..ImageIO.read() luôn xoay hình ảnh đã tải lên của tôi

ImageIO.read (InputStream)

để có được BufferedImage đối tượng

đây là mã :

public static BufferedImage getBufferedImageFromMultipartFile(MultipartFile file) 
throws APIException 
{ 
    BufferedImage bi = null; 

    try 
    { 
     bi = ImageIO.read(file.getInputStream()); 
    } 
    catch (IOException e) 
    { 
     throw new APIException(ErrorCode.SERVER_ERROR, e); 
    } 

    return bi; 
} 

vấn đề là khi tôi cố gắng để tải lên một bức tranh có chiều cao hơn chiều rộng như 3264 x 2448 (chiều cao x chiều rộng), các kết quả luôn là hình ảnh đã được xoay (2448 x 3264).

Có giải pháp nào để giải quyết vấn đề này không?

Đây có phải là lỗi hoặc bất kỳ thông số API được xác định nào không?

Thx.

PS. xin lỗi cho tiếng anh của tôi: D

+0

Tôi đã tìm thấy câu hỏi tương tự ngay bây giờ, http://stackoverflow.com/questions/9453367/is-javax-imageio-imageio-broken-it-imports-some-images-as-rotated?rq=1. Vì vậy, vấn đề của tôi không phải là một lỗi của ImageIO nhưng nó là đặc tả API mà ImageIO không thể đọc được chi tiết hình ảnh (định dạng EXIF). CÁM ƠN. –

Trả lời

0

Vấn đề khá thú vị ... bạn có thể cố khắc phục bằng cách giới thiệu kiểm tra chiều rộng và chiều cao hình ảnh lớn hơn 2448 và 3264 và sau đó hoán đổi chiều rộng và chiều cao

Sử dụng bên dưới đoạn mã:

BufferedImage oldImage = ImageIO.read(file.getInputStream()); 

if (oldImage.getWidth() > 2448 || oldImage.getHeight() > 3264) { 

    BufferedImage newImage = new BufferedImage(oldImage.getWidth(), 
       oldImage.getHeight(), oldImage.getType()); 

    Graphics2D graphics = (Graphics2D) newImage.getGraphics(); 

    graphics.drawImage(oldImage, 0, 0, oldImage.getHeight(), 
       oldImage.getWidth(), null); 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 

    ImageIO.write(newImage, "JPG", bos); 
} 
+0

thx. để tham gia nhưng tôi nghĩ từ ngữ và ngữ pháp của tôi đang khiến bạn hiểu lầm. Bây giờ, tôi đã cải thiện câu hỏi của mình. –

+1

ok ... bây giờ rõ ràng ... gud rằng SO có câu trả lời và bạn tìm thấy nó quá :) –

5

ImageIO.read() không thể đọc được định hướng của hình ảnh nếu nó được thực hiện với thiết bị di động.

tôi đã sử dụng siêu dữ liệu-vắt để đọc metadata, tôi nghĩ rằng đó là một giải pháp tốt: github.com/drewnoakes/metadata-extractor/wiki

<dependency> 
    <groupId>com.drewnoakes</groupId> 
    <artifactId>metadata-extractor</artifactId> 
    <version>2.7.2</version> 
</dependency> 

đọc hướng nộp trong thư mục exif:

ExifIFD0Directory exifIFD0 = metadata.getDirectory(ExifIFD0Directory.class); 
int orientation = exifIFD0.getInt(ExifIFD0Directory.TAG_ORIENTATION); 

switch (orientation) { 
    case 1: // [Exif IFD0] Orientation - Top, left side (Horizontal/normal) 
    return null; 
    case 6: // [Exif IFD0] Orientation - Right side, top (Rotate 90 CW) 
    return Rotation.CW_90; 
    case 3: // [Exif IFD0] Orientation - Bottom, right side (Rotate 180) 
    return Rotation.CW_180; 
    case 8: // [Exif IFD0] Orientation - Left side, bottom (Rotate 270 CW) 
    return Rotation.CW_270; 
} 

(Rotation là một lớp từ org.imgscalr.Scalr framework Tôi sử dụng hình ảnh xoay ti).

+0

Điều này cực kỳ hữu ích. Mã với các hằng số Scalr cũng chính xác là những gì tôi cần. – Bill

Các vấn đề liên quan