【问题标题】:Compress JPG make the image turn green压缩JPG使图像变绿
【发布时间】:2011-07-16 00:51:52
【问题描述】:

当我尝试压缩 jpg 图像时,大多数情况下它都能正常工作,但是一些 jpg 图像在压缩后变成绿色。这是我的代码

public void compressImage(String filename, String fileExtension) {
    BufferedImage img = null;
    try {
        File file = new File(filename);
        img = ImageIO.read(file);

        if (fileExtension.toLowerCase().equals(".png") || fileExtension.toLowerCase().equals(".gif")) {
            //Since there might be transparent pixel, if I dont do this,
            //the image will be all black.
            for (int x = 0; x < img.getWidth(); x++) {
                for (int y = 0; y < img.getHeight(); y++) {
                    int rgb = img.getRGB(x, y);
                    int alpha = (rgb >> 24) & 0xff;
                    if (alpha != 255) {
                        img.setRGB(x, y, -1); //set white
                    }
                }
            }
        }
        Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
        //Then, choose the first image writer available
        ImageWriter writer = (ImageWriter) iter.next();
        //instantiate an ImageWriteParam object with default compression options
        ImageWriteParam iwp = writer.getDefaultWriteParam();
        //Set the compression quality
        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iwp.setCompressionQuality(0.8f);
        //delete the file. If I dont the file size will stay the same
        file.delete();
        ImageOutputStream output = ImageIO.createImageOutputStream(new File(filename));
        writer.setOutput(output);
        IIOImage image = new IIOImage(img, null, null);
        writer.write(null, image, iwp);
        writer.dispose();
    } catch (IOException ioe) {
        logger.log(Level.SEVERE, ioe.getMessage());
    }
}

【问题讨论】:

  • 出于好奇,您为什么要将ServletContext 传递给此方法?它从未使用过。
  • @Matt:好点,它来自我的旧代码。我传入ServletContext 试图找出file path,但后来我决定改为传入file path
  • 我只是在测试图像(顶部)上运行了代码,并没有影响着色。 Here's the result。它肯定是经过压缩的(246 KB vs 453 KB)。
  • 顺便说一句,你应该通用声明迭代器:Iterator&lt;ImageWriter&gt; iter = ImageIO.get...,然后你不需要强制转换,你可以这样写:ImageWriter writer = iter.next();
  • 我也刚刚在 OS X 10.6 上的 JRE 6 上运行了代码 - 也没有问题。会不会是this problem?我在 exif 标签中看到的唯一区别是原始图像的 JFIF 版本是 1.1,而处理后的图像的版本是 1.2。

标签: java compression jpeg javax.imageio image-compression


【解决方案1】:

将最终图像从YUV 转换回RGB,将恢复图像的颜色。 这种转换对我有用:cv2.cvtColor(img_file, cv2.COLOR_YUV2RGB)

【讨论】:

    【解决方案2】:

    根据经验,我知道绿色是新格式化的 YUV 内存(尤其是 YV12)的颜色。所以我的猜测是某个步骤失败了,你得到了亮度信息,但色度被搞砸了。在我看来,它在到达 Cr 平面之前就失败了。

    无论如何,祝你好运,这是一个艰难的过程。不过,您的代码看起来很奇怪——顶部奇怪的 png 特定代码是什么? AFAIK,如果您使用 .NET,您几乎可以将任何已注册的图像格式视为没有任何有趣工作的图像。

    【讨论】:

    • 这是 Java,不是 C#,所以 OP 没有使用 .NET。
    【解决方案3】:

    我也有同样的问题。在我的测试服务器中运行 java 7 oracle 并且工作正常。在我的生产服务器上运行 openJDK 1.7,压缩图像变成绿色......在某些 JAVA 版本中似乎存在错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-24
      • 1970-01-01
      • 2019-08-06
      • 2016-04-25
      • 2020-02-16
      • 2012-08-13
      • 1970-01-01
      • 2016-04-14
      相关资源
      最近更新 更多