2011-07-26 30 views
10

đầu tiên tôi muốn giải thích tình hình/yêu cầu mà dẫn đến câu hỏi:tinh khiết Java thay thế cho JAI ImageIO để phát hiện các hình ảnh CMYK

Trong ứng dụng web của chúng tôi, chúng tôi không thể hỗ trợ các hình ảnh CMYK (JPEG) kể từ IE 8 và dưới đây không thể hiển thị chúng. Vì vậy, chúng tôi cần phát hiện khi ai đó muốn tải lên một hình ảnh như vậy và từ chối nó.

Thật không may, ImageIO của Java sẽ không đọc những hình ảnh đó hoặc sẽ không cho phép tôi nhận được không gian màu được phát hiện. Từ gỡ lỗi có vẻ như JPEGImageReader nội bộ nhận được mã vùng màu 11 (có nghĩa là JCS_YCCK) nhưng tôi không thể truy cập thông tin đó một cách an toàn.

Khi truy vấn trình đọc cho các loại hình ảnh, tôi không nhận được gì cho CMYK, vì vậy tôi có thể giả định no image types = unsupported image.

Tôi đã chuyển đổi hình ảnh CMYK nguồn thành RGB bằng công cụ hình ảnh để kiểm tra xem nó có thể đọc được không (tôi đã cố gắng mô phỏng các bước của quản trị viên khi nhận được thông báo "Không hỗ trợ CMYK"). Tuy nhiên, JPEGImageReader sẽ không đọc hình ảnh đó vì nó giả định (chú thích trong nguồn!) Không gian màu RGB 3 thành phần nhưng tiêu đề hình ảnh báo cáo 4 thành phần (có thể là RGBA hoặc ARGB) và do đó IllegalArgumentException bị ném. Vì vậy, ImageIO không phải là một lựa chọn vì tôi không thể nhận được không gian màu của hình ảnh một cách đáng tin cậy và tôi không thể nói cho quản trị viên biết tại sao một hình ảnh khác tốt (nó có thể được hiển thị bởi trình duyệt) sẽ không được chấp nhận do một số lỗi nội bộ.

Điều này đã khiến tôi thử JAI ImageIO có công việc tuyệt vời và đọc chính xác tất cả hình ảnh thử nghiệm của tôi.

Tuy nhiên, vì chúng tôi đang triển khai ứng dụng của mình trong JBoss có thể lưu trữ các ứng dụng khác, chúng tôi muốn giữ chúng càng tách biệt càng tốt. AFAIK, tôi cần phải cài đặt JAI ImageIO vào JRE hoặc làm cho các libs sẵn có để sử dụng chúng, và do đó các ứng dụng khác có thể truy cập chúng, điều này có thể gây ra các tác dụng phụ (ít nhất chúng ta có để kiểm tra rất nhiều để đảm bảo đó không phải là trường hợp).

Đó là giải thích cho câu hỏi và tại đây lại xuất hiện: Có bất kỳ thay thế Java thuần túy nào cho JAI ImageIO phát hiện và chuyển đổi hình ảnh CMYK một cách đáng tin cậy không?

Cảm ơn trước,

Thomas

Trả lời

10

Tôi đã tìm thấy giải pháp phù hợp với nhu cầu của mình: Apache Commons Sanselan. Thư viện này đọc tiêu đề JPEG khá nhanh và chính xác (ít nhất là tất cả các hình ảnh thử nghiệm của tôi) cũng như một số định dạng hình ảnh khác.

Nhược điểm là nó sẽ không đọc dữ liệu ảnh JPEG, nhưng tôi có thể làm điều đó với các công cụ JRE cơ bản.

hình ảnh Reading JPEG cho chuyển đổi khá dễ dàng (những cái mà ImageIO từ chối để đọc, quá):

JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new FileInputStream(new File(pFilename))); 
BufferedImage sourceImg = decoder.decodeAsBufferedImage(); 

Sau đó, nếu Sanselan nói với tôi những hình ảnh thực sự là CMYK, tôi nhận được raster hình ảnh nguồn và chuyển đổi bản thân mình:

for(/*each pixel in the raster, which is represented as int[4]*/) 
{ 
    double k = pixel[3]/255.0; 

    double r = (255.0 - pixel[0])*k; 
    double g = (255.0 - pixel[1])*k; 
    double b = (255.0 - pixel[2])*k; 
} 

Điều này cho kết quả khá tốt trong hình ảnh RGB không quá sáng hoặc tối. Tuy nhiên, tôi không chắc chắn tại sao nhân với k ngăn cản sự sáng. JPEG thực sự được giải mã trong mã gốc và chuyển đổi CMYK-> RGB tôi nhận được trạng thái khác nhau, tôi chỉ thử nhân để xem kết quả trực quan.

Nếu ai cũng có thể làm sáng tỏ điều này, tôi sẽ biết ơn.

+0

Tôi gặp vấn đề tương tự với hình ảnh JPEG JAI và CMYK. Bạn có sử dụng phương pháp đó đã được sản xuất? Trải nghiệm của bạn thế nào? Tôi đoán bạn sử dụng 'Sanselan.getImageInfo (...). GetColorType() == ImageInfo.COLOR_TYPE_CMYK' ([ImageInfo] (http://commons.apache.org/sanselan/api-release/org/apache/sanselan /ImageInfo.html)) để kiểm tra xem đó có phải là hình ảnh CMYK không? –

+0

@bene Có, trước tiên chúng tôi kiểm tra xem Sanselan có tìm thấy hồ sơ ICC không và nếu có thì hãy dùng loại không gian màu của nó nhưng nếu không, chúng tôi sử dụng 'ImageInfo.getColorType()'. Chúng tôi đang sử dụng điều này trong sản xuất và không có bất kỳ vấn đề cho đến nay, tuy nhiên, tôi phải thừa nhận rằng chúng tôi hiện đang không xử lý nhiều hình ảnh. Trong tương lai, chúng tôi sẽ có cơ sở dữ liệu phương tiện truyền thông của riêng chúng tôi sẽ xử lý hàng ngàn hình ảnh và sau đó chúng tôi sẽ có thông tin đáng tin cậy hơn về sự sẵn sàng sản xuất của phương pháp đó. Chỉ cần một mặt lưu ý: chuyển đổi CMYK Tiffs sản xuất một số màu sắc đáng chú ý và chúng tôi đã không quản lý để thoát khỏi điều đó được nêu ra. – Thomas

+1

Hôm nay tôi nhấn một hình ảnh mà ICCProfile của Sanselan có ColorSpaceType CMYK trong khi ColorType của ImageInfo là RGB. Không gian màu thực sự là RGB. Tự hỏi nếu bạn có cùng một vấn đề. –

2

Trong ứng dụng web của chúng tôi, chúng tôi không thể hỗ trợ các hình ảnh CMYK (JPEG) kể từ IE 8 và dưới đây không thể hiển thị chúng. Do đó, chúng tôi cần phát hiện khi ai đó muốn tải lên hình ảnh đó và từ chối hình ảnh đó.

Tôi không đồng ý với số "Vì vậy, chúng tôi cần phát hiện khi ai đó muốn tải lên hình ảnh đó và từ chối". Một chính sách thân thiện với người dùng hơn nhiều sẽ là chuyển đổi nó thành một cái gì đó khác với CMYK.

Phần còn lại của bài đăng của bạn hơi bối rối khi thấy rằng bạn yêu cầu cả hai để phát hiện và chuyển đổi, đó là hai thứ khác nhau. Một lần nữa, tôi nghĩ việc chuyển đổi hình ảnh thân thiện với người dùng hơn nhiều.

Không cần phải viết in đậm btw:

Có tinh khiết Java thay thế cho JAI ImageIO mà đáng tin cậy phát hiện và có thể chuyển đổi hình ảnh CMYK?

Java thuần túy Tôi không biết, nhưng ImageMagick hoạt động tốt để chuyển đổi hình ảnh CMYK sang RGB. Gọi ImageMagick ở phía máy chủ từ Java thực sự không phức tạp. Tôi đã từng thực hiện thủ công bằng cách gọi một quy trình bên ngoài nhưng hiện nay có các trình bao bọc như JMagickim4java.

+0

Đối với người dùng thân thiện: chuyển đổi CMYK thành RGB đôi khi làm sáng màu một chút và do đó chúng tôi muốn người dùng chuyển đổi theo cách thủ công và xác nhận màu vẫn ổn. Trong một ứng dụng khác, chúng tôi được tự do chuyển đổi bất kể điều này, vì vậy tôi đã yêu cầu cả hai. – Thomas

+0

'Không cần phải viết chữ đậm btw:' - đó chỉ là để đánh dấu câu hỏi cho những người không muốn đọc sự lộn xộn ở giữa :) – Thomas

+0

Liên quan 'ImageMagick': đó có thể là một thay thế mặc dù chúng tôi cần để cài đặt nó. Cảm ơn đề nghị đó. – Thomas

4

Tôi đã đăng một Java thuần túy solution để đọc tất cả các loại hình ảnh JPEG và chuyển đổi chúng thành RGB.

Nó được xây dựng trên các sự kiện sau đây:

  • Trong khi ImageIO không thể đọc được hình ảnh JPEG với CMYK như một hình ảnh đệm, nó có thể đọc dữ liệu pixel nguyên bản (raster).
  • Sanselan (hoặc Apache Commons Imaging như nó được gọi là bây giờ) có thể được sử dụng để đọc các chi tiết của hình ảnh CMYK.
  • Có hình ảnh với giá trị CMYK đảo ngược (lỗi Photoshop cũ).
  • Có hình ảnh với YCCK thay vì CMYK (có thể dễ dàng được chuyển đổi).
2

Hãy coi chừng một bài đăng khác như Java 7 không cho phép sử dụng trực tiếp triển khai của Sun mà không có tham số đặc biệt như được chỉ ra trong import com.sun.image.codec.jpeg.*.