Issue Using Imageio.Write Jpg File: Pink Background

Issue using ImageIO.write jpg file: pink background

You can work around this by using Toolkit.createImage(url) instead of ImageIO.read(url) which uses a different implementation of the decoding algorithm.

If you are using the JPEG encoder included with the Sun JDK then you must also ensure that you pass it an image with no alpha channel.

Example:

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));

Note: My guess is that the color profile is corrupted, and Toolkit.createImage() ignores all color profiles. If so then this will reduce the quality of JPEGs that have a correct color profile.

Writing jpg or jpeg image with ImageIO.write does not create image file

First of all I can confirm this behaviour for JavaFX 13 ea build 13. This was probably a very simplistic attempt to fix an old bug which the OP has already mentioned (image turning pink) which I reported a long time ago. The problem is that JPEGS cannot store alpha information and in the past the output was just garbled when an image with an alpha channel was written out as a JPEG. The fix now just refuses to write out the image at all instead of just ignoring the alpha channel.

A workaround is to make a copy of the image where you explicitly specify a color model without alpha channel.

Here is the original bug report which also contains the workaround: https://bugs.openjdk.java.net/browse/JDK-8119048

Here is some more info to simplify the conversion:
If you add this line to your code

BufferedImage awtImage = new BufferedImage((int)img.getWidth(), (int)img.getHeight(), BufferedImage.TYPE_INT_RGB);

and then call SwingFXUtils.fromFXImage(img, awtImage) with this as the second parameter instead of null, then the required conversion will be done automatically and the JPEG is written as expected.

ImageIO : gif to jpeg problem - the image becomes pink

Perhaps, pink is defined as the transparency color for the gif image. If so, the following example might work. Basically, a new image is created and the "backgound color" is explicitly set to whatever is passed in.

public static byte[] convert(byte[] bytes, Color backgroundColor) throws Exception
{
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
BufferedImage bufferedImage = ImageIO.read(inputStream);
BufferedImage newBi = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) newBi.getGraphics();
g2d.drawImage(bufferedImage, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), backgroundColor, null);
bufferedImage.getHeight(), null);
ByteArrayOutputStream osByteArray = new ByteArrayOutputStream();
ImageOutputStream outputStream = ImageIO.createImageOutputStream(osByteArray);
ImageIO.write(newBi, "jpg", outputStream);
outputStream.flush();
outputStream.close();
return osByteArray.toByteArray();
}

Looks like this might be related.

Image saved in JavaFX as jpg is pink toned

I found a solution on Oracle forums. As widely discussed, the problem is in alpha-channel that needs to be excluded from the source image, targeted for .jpg save. I also rearranged my code to make it shorter. The workaround is:

// Get buffered image:
BufferedImage image = SwingFXUtils.fromFXImage(myJavaFXImage, null);

// Remove alpha-channel from buffered image:
BufferedImage imageRGB = new BufferedImage(
image.getWidth(),
image.getHeight(),
BufferedImage.OPAQUE);

Graphics2D graphics = imageRGB.createGraphics();

graphics.drawImage(image, 0, 0, null);

ImageIO.write(imageRGB, "jpg", new File("/mydir/foto.jpg"));

graphics.dispose();

Fixed in Java 8: https://bugs.openjdk.java.net/browse/JDK-8114609

JPEG image with wrong colors

I found a solution now, that works, at least if my resulting image is also a JPEG:
First I read the image (from byte array imageData), and most important, I also read the metadata.

InputStream is = new BufferedInputStream(new ByteArrayInputStream(imageData));
Image src = null;
Iterator<ImageReader> it = ImageIO.getImageReadersByMIMEType("image/jpeg");
ImageReader reader = it.next();
ImageInputStream iis = ImageIO.createImageInputStream(is);
reader.setInput(iis, false, false);
src = reader.read(0);
IIOMetadata imageMetadata = reader.getImageMetadata(0);

Now i'd do some converting (i.e. shrink in size) ... and at last I'd write the result back as a JPEG image. Here it is most important to pass the metadata we got from the original image to the new IIOImage.

Iterator<ImageWriter> iter = ImageIO.getImageWritersByMIMEType("image/jpeg");
ImageWriter writer = iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(jpegQuality);
ImageOutputStream imgOut = new MemoryCacheImageOutputStream(out);
writer.setOutput(imgOut);
IIOImage image = new IIOImage(destImage, null, imageMetadata);
writer.write(null, image, iwp);
writer.dispose();

Unfortunately, if I'd write a PNG image, I still get the wrong colors (even if passing the metadata), but I can live with that.

Change in color while using ImageIO.read()

This problem is cause by a mismatch between reading/writing (creating/using) an image
that contains alpha (transparency) but you are expecting it to contain no alpha (or the inverse).
For example, if your image is BufferedImage.TYPE_4BYTE_ABGR and you output it
to a file type that does not support alpha (transparency) , or you writer does not
support alpha, it will look like your sample after reading and displaying it.

Use type PNG (supports alpha channel) not JPG (does not support alpha channel)



Related Topics



Leave a reply



Submit