JPEG图像颜色错误 [英] JPEG image with wrong colors

查看:367
本文介绍了JPEG图像颜色错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种方法可以读取图像,转换它们(大小,格式)并将它们写回来。这总是很好用,但现在我遇到了一些显然包含一些元数据(IPTC)的JPEG图像(来自新闻社)。转换这些图像时,颜色都是错误的。我的第一个猜测是,那些是CMYK图像,但它们不是。

I have a method that reads images, converts them (size, format) and writes them back. This always worked very well, but now I've come across some JPEG images (from a Press Agency) that obviously contain some meta-data (IPTC). When converting those images, the colors are all wrong. My first guess was, that those are CMYK images but they are not.

问题必须来自阅读,因为无论我是否将图像转换为较小的JPEG或PNG,它看起来总是一样。

The problem must come from the reading, because it doesn't matter whether I convert the image to a smaller JPEG or a PNG, it always looks the same.

首先,我使用 ImageIO.read()阅读图像。我现在通过 ImageIO.getImageReadersByMIMEType()获取实际的 ImageReader 并尝试通过设置告诉读者忽略元数据 ignoreMetadata 参数 ImageReader #setInput(对象输入,布尔值为seekForwardOnly,boolean ignoreMetadata)但没有成功。

At first, I used ImageIO.read() to read the image. I now get the actual ImageReader via ImageIO.getImageReadersByMIMEType() and tried to tell the reader to ignore meta data by setting the ignoreMetadata parameter of ImageReader#setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) but had no success.

然后我创建了一个没有元数据的图像版本(使用Fireworks)。该图像转换正确。

Then I created a version of the image without the metadata (using Fireworks). That image is converted correctly.

唯一的区别是,使用无效图像读取器变量的值 colorSpaceCode 2 ,而对于工作图像,值为 3 。还有一个 outColorSpaceCode ,两张图片的 2

The only difference I could find out, is, that with the not-working image the value of the reader's variable colorSpaceCode is 2, whilest with the working image, the value is 3. There's also an outColorSpaceCode which is 2 for both images.

作为读者来源评论仅说由setImageData本机代码回调设置。修改后的IJG + NIFTY颜色空间代码我现在真的被卡住了。所以任何帮助都会非常感激。

As the source comment of the reader only says Set by setImageData native code callback. A modified IJG+NIFTY colorspace code I'm really stuck now. So any help would be much appreciated.

你可以通过此处并单击下载。下图左侧显示了我从原始图像中获得的内容,右侧显示了它应该是什么样子。

You can get original image (~3 MB) by going here and clicking download. The left image below shows what I get from the original image, the right shows what it should look like.


推荐答案

我现在找到了一个解决方案,至少如果我的结果图像也是JPEG:
首先我读取图像(来自字节数组imageData),最重要的是,我还读取了元数据。

I found a solution now, that works, at least if my resulting image is also a JPEG: First I read the image (from byte array imageData), and most important, I also read the metadata.

InputStream is = new BufferedInputStream(new ByteArrayInputStream(imageData));
Image src = null;
Iterator<ImageReader> it = ImageIO.getImageReadersByMIMEType("image/jpeg");
ImageReader reader = it.next();
ImageInputStream iis = ImageIO.createImageInputStream(is);
reader.setInput(iis, false, false);
src = reader.read(0);
IIOMetadata imageMetadata = reader.getImageMetadata(0);

现在我做一些转换(即缩小尺寸)......最后我说d将结果写回JPEG图像。这里最重要的是将我们从原始图像获得的元数据传递给新的 IIOImage

Now i'd do some converting (i.e. shrink in size) ... and at last I'd write the result back as a JPEG image. Here it is most important to pass the metadata we got from the original image to the new IIOImage.

Iterator<ImageWriter> iter = ImageIO.getImageWritersByMIMEType("image/jpeg");
ImageWriter writer = iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(jpegQuality);
ImageOutputStream imgOut = new MemoryCacheImageOutputStream(out);
writer.setOutput(imgOut);
IIOImage image = new IIOImage(destImage, null, imageMetadata);
writer.write(null, image, iwp);
writer.dispose();

不幸的是,如果我写了一个PNG图像,我仍然会得到错误的颜色(即使通过元数据),但我可以忍受。

Unfortunately, if I'd write a PNG image, I still get the wrong colors (even if passing the metadata), but I can live with that.

这篇关于JPEG图像颜色错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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