Сжать JPG, чтобы изображение стало зеленым

Когда я пытаюсь сжать изображение в формате 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());
    }
}

Исходное изображениеСжать изображение. Изображение станет зеленым


person Thang Pham    schedule 15.03.2011    source источник
comment
Из любопытства, почему вы передаете ServletContext этому методу? Он никогда не используется.   -  person Matt Ball    schedule 15.03.2011
comment
@Matt: Хороший вопрос, это было из моего старого кода. Я пропускаю ServletContext, пытаясь понять file path, но потом решаю вместо этого передать file path   -  person Thang Pham    schedule 15.03.2011
comment
Я просто запустил код на тестовом изображении (верхнем), и это не повлияло на окраску. Вот результат. Он определенно был сжат (246 КБ против 453 КБ).   -  person Matt Ball    schedule 15.03.2011
comment
Кстати, вы должны объявить итератор в общем: Iterator<ImageWriter> iter = ImageIO.get..., тогда вам не нужно приводить, вы можете просто написать это: ImageWriter writer = iter.next();   -  person Matt Ball    schedule 15.03.2011
comment
@Matt: Когда ты сказал, что сжатое изображение не изменило цвет, ты запустил мой код, Мэтт?   -  person Thang Pham    schedule 16.03.2011
comment
Да, я запустил ваш код. JDK 6 u24 в Windows 7 x64.   -  person Matt Ball    schedule 16.03.2011
comment
Я также только что запустил код на JRE 6 в OS X 10.6 - там тоже нет проблем. Может быть, это эта проблема? Единственная разница, которую я увидел в тегах exif, заключалась в том, что версия JFIF исходного изображения — 1.1, а версия обработанного изображения — 1.2.   -  person Matt Ball    schedule 16.03.2011


Ответы (2)


По опыту знаю, что зеленый цвет - это цвет только что отформатированной памяти YUV (в частности, YV12). Итак, я предполагаю, что какой-то шаг терпит неудачу, и вы получаете информацию о яркости, но цветность испорчена. Мне кажется, что он выходит из строя, прежде чем доберется до самолета Cr.

В любом случае, удачи, это тяжело. Однако ваш код выглядит странно — что за странный код, специфичный для png, вверху? Насколько я знаю, если вы используете .NET, вы можете обращаться с любым зарегистрированным форматом изображения так же, как если бы это было изображение без какой-либо забавной работы.

person kidjan    schedule 06.04.2011
comment
Это Java, а не C#, поэтому ОП не использует .NET. - person Matt Ball; 17.05.2011

У меня точно такая же проблема. На моем тестовом сервере запускается java 7 oracle и все работает нормально. На моем производственном сервере запущен openJDK 1.7, и сжатые изображения становятся зелеными... Кажется, это ошибка в некоторых версиях JAVA.

person thiagoms83    schedule 03.08.2016