С помощью файла 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)
Ответы
Ответ 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, не осознавая этого.