用于检测CMYK图像的JAI ImageIO的纯Java替代品 [英] Pure Java alternative to JAI ImageIO for detecting CMYK images

查看:178
本文介绍了用于检测CMYK图像的JAI ImageIO的纯Java替代品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我想解释导致问题的情况/要求:

first I'd like to explain the situation/requirements that lead to the question:

在我们的网络应用程序中,我们无法支持CMYK图像(JPEG) IE 8及以下版本无法显示它们。
因此我们需要检测有人想要上传这样的图像并拒绝它。

In our web application we can't support CMYK images (JPEG) since IE 8 and below can't display them. Thus we need to detect when someone wants to upload such an image and deny it.

不幸的是,Java的ImageIO不会读取这些图像或不会启用我得到检测到的颜色空间。从调试看起来似乎 JPEGImageReader 在内部获取颜色空间代码11(这意味着 JCS_YCCK )但我不能安全地访问该信息。

Unfortunately, Java's ImageIO won't read those images or would not enable me to get the detected color space. From debugging it seems like JPEGImageReader internally gets the color space code 11 (which would mean JCS_YCCK) but I can't safely access that information.

当查询读者的图像类型时,我没有得到任何CMYK,所以我可能会假设没有图像类型=不支持的图像

When querying the reader for the image types I get nothing for CMYK, so I might assume no image types = unsupported image.

我使用成像工具将源CMYK图像转换为RGB,以便测试它是否可读(我试图在获取消息时模拟管理员的步骤没有CMYK支持)。但是, JPEGImageReader 不会读取该图像,因为它假定(在源中注释!)3分量RGB颜色空间但图像标题报告4个组件(可能是RGBA或ARGB),因此抛出 IllegalArgumentException

I converted the source CMYK image to RGB using an imaging tool in order to test whether it would then be readable (I tried to simulate the admin's steps when getting the message "No CMYK supported"). However, JPEGImageReader would not read that image, since it assumes (comment in the source!)3-component RGB color space but the image header reports 4 components (maybe RGBA or ARGB) and thus an IllegalArgumentException is thrown.

因此,ImageIO不是一个选项因为我无法可靠地获得图像的色彩空间,所以我无法告诉管理员为什么由于某些内部错误而无法接受其他精细图像(可以由浏览器显示)。


Thus, ImageIO is not an option since I can't reliably get the color space of an image and I can't tell the admin why an otherwise fine image (it can be displayed by the browser) would not be accepted due to some internal error.

这让我尝试了JAI ImageIO,其 c> CLibJPEGImageReader 一个出色的工作,并正确读取我的所有测试图像。

This led me to try JAI ImageIO whose CLibJPEGImageReader does an excellent job and correctly reads all my test images.

但是,由于我们将应用程序部署在可能托管其他应用程序的JBoss中,我们希望让它们尽可能隔离。 AFAIK,我需要将JAI ImageIO安装到JRE或者使本机库可用以便使用它们,因此其他应用程序也可以访问它们,这可能会导致副作用(至少我们有测试很多,以确保不是这样。)

However, since we're deploying our application in a JBoss that might host other applications as well, we'd like to keep them as isolated as possible. AFAIK, I'd need to install JAI ImageIO to the JRE or otherwise make the native libs available in order to use them, and thus other applications might get access to them as well, which might cause side effects (at least we'd have to test a lot to ensure that's not the case).

这是问题的解释,这里又来了:
有没有JAI ImageIO的纯Java替代品可以可靠地检测并可能转换CMYK图像吗?

That's the explanation for the question, and here it comes again: Is there any pure Java alternative to JAI ImageIO which reliably detects and possibly converts CMYK images?

提前致谢,

Thomas

推荐答案

我找到了一个可以满足我们需求的解决方案: Apache Commons Sanselan 。这个库非常快速准确地读取JPEG标题(至少是我的所有测试图像)以及许多其他图像格式。

I found a solution that is ok for our needs: Apache Commons Sanselan. This library reads JPEG headers quite fast and accurate (at least all my test images) as well as a number of other image formats.

缺点是它不会读取JPEG图像数据,但我可以使用基本的JRE工具。

The downside is that it won't read JPEG image data, but I can do that with the basic JRE tools.

读取JPEG图像进行转换非常简单(那些 ImageIO 也拒绝阅读):

Reading JPEG images for conversion is quite easy (the ones that ImageIO refuses to read, too):

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

然后如果Sanselan告诉我图像实际上是CMYK,我会得到源图像的栅格并转换成自己:

Then if Sanselan tells me the image is actually CMYK, I get the source image's raster and convert myself:

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;
}

这样可以使RGB图像不会太亮或太暗。但是,我不确定为什么乘以 k 会阻止增亮。 JPEG实际上是用本机代码解码的,CMYK-> RGB转换得到了不同的状态,我只是尝试乘法来看到视觉效果。

This give quite good results in the RGB images not being too bright or dark. However, I'm not sure why multiplying with k prevents the brightening. The JPEG is actually decoded in native code and the CMYK->RGB conversion I got states something different, I just tried the multiply to see the visual result.

如果有人可以对此有所了解,我将不胜感激。

If anybody could shed some light on this, I'd be grateful.

这篇关于用于检测CMYK图像的JAI ImageIO的纯Java替代品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆