Подтвердить что ты не робот

С помощью файла ImageIO.write jpg

Я использую следующий код для записи файла jpg:

String url="http://img01.taobaocdn.com/imgextra/i1/449400070/T2hbVwXj0XXXXXXXXX_!!449400070.jpg";
String to="D:/temp/result.jpg";
ImageIO.write(ImageIO.read(new URL(url)),"jpg", new File(to));

Но я получаю result.jpg розовое фоновое изображение:

alt text

Как решить эту проблему? Можете ли вы дать мне пример кода? (в библиотеке J2SE)

4b9b3361

Ответ 1

Вы можете обойти это, используя Toolkit.createImage(url) вместо ImageIO.read(url), который использует другую реализацию алгоритма декодирования.

Если вы используете кодировщик JPEG, входящий в состав Sun JDK, вы также должны убедиться, что вы передаете ему изображение без альфа-канала.

Пример:

private static final int[] RGB_MASKS = {0xFF0000, 0xFF00, 0xFF};
private static final ColorModel RGB_OPAQUE =
    new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]);

    // ...

String sUrl="http://img01.taobaocdn.com/imgextra/i1/449400070/T2hbVwXj0XXXXXXXXX_!!449400070.jpg";
URL url = new URL(sUrl);
Image img = Toolkit.getDefaultToolkit().createImage(url);

PixelGrabber pg = new PixelGrabber(img, 0, 0, -1, -1, true);
pg.grabPixels();
int width = pg.getWidth(), height = pg.getHeight();

DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight());
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null);
BufferedImage bi = new BufferedImage(RGB_OPAQUE, raster, false, null);

String to = "D:/temp/result.jpg";
ImageIO.write(bi, "jpg", new File(to));

Примечание. Предполагается, что цветовой профиль поврежден, а Toolkit.createImage() игнорирует все цветовые профили. Если это так, это уменьшит качество JPEG, имеющего правильный цветовой профиль.

Ответ 2

У меня были подобные проблемы. Но затем я решил это, используя этот

   BufferedImage image = new BufferedImage(width, height,
            BufferedImage.TYPE_INT_RGB); 

   //do something to populate the image
   //such as
   image.setRGB( x, y, pixelValue); //set your own pixels color



   ImageIO.write(image, "jpg", new File("D:\\test.jpg"));

Обратите внимание, что я использую Java версию 1.6.0_25-b06 и он просто отлично работает.

Возможно, вы можете проверить версию Java.

Ответ 3

Это работает для меня:

int w = originalImage.getWidth();
int h = originalImage.getHeight();
BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
int[] rgb = originalImage.getRGB(0, 0, w, h, null, 0, w);
newImage.setRGB(0, 0, w, h, rgb, 0, w);

Ответ 4

BufferedImage originalImage = ImageIO.read(getContent());
BufferedImage newImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);

    for (int x = 0; x < originalImage.getWidth(); x++) {
        for (int y = 0; y < originalImage.getHeight(); y++) {
            newImage.setRGB(x, y, originalImage.getRGB(x, y));
        }
    }

это сделало трюк для меня

Ответ 5

Я столкнулся с такой же проблемой при чтении и записи изображений с помощью ImageIO. Прочитав ответы здесь, я изменил свою JRE - от openjdk version "1.8.0_91" до HotSpot java version "1.8.0_102". Подсказка не была очевидна в ответе finnw, но стоит попробовать; -)

И, таким образом, проблема решена! Поэтому, если вы используете OpenJDK JRE и можете изменять JRE, меняя его HotSpot, вам не нужно будет менять код.

Ответ 6

  • для меня проблема была не в чтении, а в написании
  • ImageIO с радостью напишет JPG файлы из ARGB BufferedImages
  • Браузеры/другие программы затем интерпретируют этот 4-канальный файл как цвет CMYK или что-то еще, что приводит к эффекту, описанному в этом вопросе.
  • решение для меня: убедитесь, что BufferedImage, переданный в ImageIO.write, имеет тип RGB (не ARGB)
  • Это также объясняет, почему проблема возникает только при сохранении в jpeg, но не при сохранении в png
  • Мне потребовалось много времени, чтобы понять, потому что мои собственные инструменты изображения всегда конвертируются в ARGB на лету, поэтому я всегда передавал изображение ARGB в ImageIO.write, не осознавая этого.