使用 java 缩略图或 imgscalr 调整 jpeg 图像大小时的粉红色/红色色调

问题描述:

我正在尝试使用两个库(thumbnailator 和 imgscalr)转换图像(下面的 url).我的代码适用于大多数图像,只有少数图像在转换后具有粉红色/红色调.

I am trying to convert an image (url below) using two libraries (thumbnailator and imgscalr. My code works on most of the images except a few which after conversion have a pink/reddish tint.

我正在尝试了解原因并欢迎任何建议.

I am trying to understand the cause and would welcome any recommendation.

注意 - 此图像的图像类型为 5,即 BufferedImage.TYPE_3BYTE_BGR,我使用的是 Java 7

Note - Image type of this image is 5 i.e BufferedImage.TYPE_3BYTE_BGR and i am using Java 7

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

使用 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();

我经常收到这个问题(imgscalr 的作者)——问题是几乎总是你读/写出来的不同文件格式,并且 ALPHA 通道导致您的颜色通道之一 (R/G/B) 从生成的文件中被剔除.

I get this question a lot (author of imgscalr) -- the problem is almost always that you are reading/writing out different file formats and the ALPHA channel is causing one of your color channels (R/G/B) to be culled from the resulting file.

例如,如果您读入一个 ARGB(4 通道)文件并将其写为 JPG(3 通道) - 除非您有目的地自己操作图像类型并将旧图像直接渲染为新图像,你会得到一个带有ARG"频道的文件……或者更具体地说,只有红色和绿色 - 没有蓝色.

For example, if you read in a file that was ARGB (4 channel) and wrote it out as a JPG (3 channel) - unless you purposefully manipulate the image types yourself and render the old image to the new one directly, you will get a file with a "ARG" channels... or more specifically, just Red and Green - no Blue.

PNG 支持 alpha 通道而 JPG 不支持,所以请注意这一点.

PNG supports an alpha channel and JPG does not, so be aware of that.

解决此问题的方法是有目的地创建正确类型(RGB、ARGB 等)的适当 BufferedImage 并使用 destImage.getGraphics() 调用将一个图像渲染到另一个之前将其写入磁盘并重新编码.

The way to fix this is to purposefully create appropriate BufferedImage's of the right type (RGB, ARGB, etc.) and using the destImage.getGraphics() call to render one image to the other before writing it out to disk and re-encoding it.

Sun 和 Oracle 从未使 ImageIO 库足够智能以在写入不同文件类型时检测不受支持的通道,因此这种行为一直发生:(

Sun and Oracle have NEVER made the ImageIO libraries smart enough to detect the unsupported channels when writing to differing file types, so this behavior happens all the time :(

希望有帮助!