2014-09-30 24 views
5

Tôi đang cố gắng chuyển đổi hình ảnh (url bên dưới) bằng hai thư viện (thumbnailator và imgscalr. Mã của tôi hoạt động trên hầu hết các hình ảnh ngoại trừ một số sau khi chuyển đổi có một màu hồng/đỏ màuMàu hồng/Đỏ nhạt trong khi thay đổi kích thước hình ảnh jpeg bằng cách sử dụng hình thu nhỏ java hoặc imgscalr

tôi cố gắng để hiểu được nguyên nhân và tôi hoan nghênh bất cứ đề nghị

Note -.. loại ảnh của hình ảnh này là 5 ví dụ BufferedImage.TYPE_3BYTE_BGR và tôi đang sử dụng Java

enter image description hereenter image description here

Sử dụng Thumbnailator

Thumbnails.of(fromDir.listFiles())     
        .size(thumbnailWidth, thumbnailHeight) 
        .toFiles(Rename.SUFFIX_HYPHEN_THUMBNAIL); 

Sử dụng imgscalr

BufferedImage bufferedImage = ImageIO.read(file); 
    final BufferedImage jpgImage; 

    LOG.debug("image type is =[{}] ", bufferedImage.getType()); 

    BufferedImage scaledImg = Scalr.resize(bufferedImage, Method.ULTRA_QUALITY, thumbnailWidth, thumbnailHeight, Scalr.OP_ANTIALIAS); 


    File thumbnailFile = new File(fromDirPath + "/" + getFileName(file.getName()) +THUMBNAIL_KEYWORD + ".png"); 

    ImageIO.write(scaledImg, getFileExtension(file.getName()), thumbnailFile); 

    bufferedImage.flush(); 
    scaledImg.flush(); 
+0

tôi nghĩ rằng vấn đề là JPEGImageReader hiểu sai dữ liệu JPEG, và giả định nó là RGB, chứ không phải là YCbCr (đó là những gì nó thực sự là). Điều gì sẽ xảy ra nếu bạn cố gắng hiển thị, hoặc viết (như PNG, không mở rộng) 'bufferedImage' từ mã imgscalr ở trên? Nó vẫn có vẻ không chính xác? Hay nó chỉ xảy ra sau khi chia tỷ lệ/lưu trữ dưới dạng JPEG? – haraldK

+0

@haraldK - Màu tương tự. – user749665

+0

Tôi khuyên bạn nên thử [JPEG plugin cho ImageIO] (https://github.com/haraldk/TwelveMonkeys#jpeg). Nó thường làm một công việc tốt hơn so với mặc định 'JPEGImageReader', khi xác định không gian màu đầu ra. Một trong những thư viện được đề cập đã được đóng gói sẵn với phiên bản cũ hơn của plugin của tôi, đảm bảo bạn nhận được phiên bản mới nhất, vì phiên bản kèm theo có lỗi liên quan đến vấn đề này. – haraldK

Trả lời

4

tôi nhận được câu hỏi này rất nhiều (tác giả của imgscalr) - vấn đề là hầu như luôn luôn hai người là bạn đọc/ghi các định dạng tệp khác nhau và kênh ALPHA đang khiến một trong các kênh màu của bạn (R/G/B) bị hủy khỏi siêu tệp. Ví dụ, nếu bạn đọc trong một tệp là ARGB (4 kênh) và đã ghi nó thành JPG (3 kênh) - trừ khi bạn cố tình thao tác các loại hình ảnh và hiển thị trực tiếp hình ảnh cũ sang hình ảnh mới , bạn sẽ nhận được tệp có kênh "ARG" ... hoặc cụ thể hơn, chỉ là Đỏ và Xanh lục - không có Xanh dương.

PNG hỗ trợ kênh alpha và JPG không, vì vậy hãy lưu ý điều đó.

Cách khắc phục điều này là tạo mục đích thích hợp BufferedImage của đúng loại (RGB, ARGB, v.v.) và sử dụng cuộc gọi destImage.getGraphics() để hiển thị một hình ảnh cho người khác trước khi ghi nó ra đĩa và mã hóa lại .

Sun và Oracle đã không bao giờ làm cho các thư viện ImageIO đủ thông minh để phát hiện các kênh không được hỗ trợ khi viết cho các loại tập tin khác nhau, vì vậy hành vi này xảy ra mọi lúc :(

Hy vọng rằng sẽ giúp!

+0

Cảm ơn Riyad. Tôi sẽ thử điều này ngay khi có thể. – user749665

+0

Vâng? Bạn đã thử chưa? – bashan

0

Sau đây đoạn mã giải quyết vấn đề của tôi:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

    Thumbnails.of(new ByteArrayInputStream(imageByteArray)) 
    .outputFormat("jpg") 
    .size(200, 200) 
    .toOutputStream(outputStream); 

    return baos.toByteArray(); 

tôi đang sử dụng Thumbnailator và mã đã được đăng ở đây: https://github.com/coobird/thumbnailator/issues/23

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