Change in color while using ImageIO.read() - java

I am trying to read images from external directory and for that I am using
bufferedImage image=ImageIO.read(new File(imagefile));
jlabel.seticon(new imageicon(image));
and getting a drastic change in colors. I tried many other things like:
bufferedImage image=ImageIO.read(new File(imagefile));
bufferedImage img=new bufferedImage(image.getWidth(),image.getHeight(),bufferedImage.TYPE_INT_RGB);
and I tried:
img.setData(image.getData();
jlabel.seticon(new imageicon(image));
and I tried:
Iterator readers = ImageIO.getImageReadersByFormatName("JPEG");
ImageReader reader = null;
while(readers.hasNext()) {
reader = (ImageReader)readers.next();
if(reader.canReadRaster()) {
break;
}
}
ImageInputStream input = ImageIO.createImageInputStream(f);
reader.setInput(input);
Raster raster = reader.readRaster(0, null);
BufferedImage bi = new BufferedImage(raster.getWidth(), raster.getHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
bi.getRaster().setRect(raster);
but result are still same
http://i.stack.imgur.com/jNVm0.jpg
Here is an example of the issue:
The minimal code for viewing is:
bufferedImage image=ImageIO.read(new File(imagefile));
jlabel.seticon(new imageicon(image));
lbitem.setIcon(im);
and for storing
File f = new File(s);
long size=f.length();
FileInputStream fis1=new FileInputStream(f);
FileOutputStream fos2=new FileOutputStream("src/image/"+tfpn.getText()+".jpg");
byte b[]=new byte[1000];
int r=0;
long count=0;
while(true)
{
r=fis1.read(b,0,1000);
fos2.write(b,0,1000);
count = count+r;
if(count==size)
break;
System.out.println(count);
}
What could be causing the bad colors?

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

BufferedImageOp Kernel Convolution not doing anything

I am attempting to perform a basic kernel convolution pass on an image using the BufferedImageOp package in java.awt.image. This is the code I have:
BufferedImage img = null;
File f = null;
//read image
try {
f = new File("keys.JPG");
img = ImageIO.read(f);
} catch (IOException e) {
System.out.println(e);
}
float[] gaussian = {
1/16f, 1/8f, 1/16f,
1/8f, 1/4f, 1/8f,
1/16f, 1/8f, 1/16f,
};
BufferedImageOp op = new ConvolveOp(new Kernel(3, 3, gaussian));
BufferedImage dest = op.filter(img, null);
File outputfile = new File("image.jpg");
ImageIO.write(dest, "jpg", outputfile);
My code attempts to load the image keys.JPG and then convolve this image with the Gaussian blur kernel and save the image to the file image.jpg. When I run the code, it processes for a bit then terminates and saves the image successfully but when I compare the original and the new images, they are identical.
Looking online at some code examples, my code should work. Am I missing something?
Thanks
As #haraldK mentioned, my image was too large to notice a difference. The code works as expected.

CMYK Image display on pdf using pdfbox

I am trying to create pdf in java using pdfbox 1.8, but problem is I am not able to show CMYK image on pdf so I try to solution on same like below code:
File filePath = new File("C:/Users/msuryawanshi/Documents/10734730431625_C1LA.jpg");
JPEGImageDecoder jpegDecoder = JPEGCodec.createJPEGDecoder(new FileInputStream(filePath));
BufferedImage image = jpegDecoder.decodeAsBufferedImage();
imageUrl = "http://extranet.handgards.com/gs1/10734730431625_C1LA.jpg";
File f = new File("C:/Users/msuryawanshi/Documents/10734730431625_C1LA.jpg");
String url = "http://extranet.handgards.com/gs1/10734730431625_C1LA.jpg";
Iterator readers = ImageIO.getImageReadersByFormatName("JPEG");
ImageReader reader = null;
while (readers.hasNext()) {
reader = (ImageReader) readers.next();
if (reader.canReadRaster()) {
break;
}
}
//Stream the image file (the original CMYK image)
ImageInputStream input = ImageIO.createImageInputStream(f);
reader.setInput(input);
//Read the image raster
Raster raster = reader.readRaster(0, null);
//Create a new RGB image
BufferedImage bi = new BufferedImage(raster.getWidth(), raster.getHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
//Fill the new image with the old raster
bi.getRaster().setRect(raster);
PDXObjectImage ximage = new PDPixelMap(document, bi);
contentStream.drawXObject(ximage, margin + 5, texty, 170, 100);
but image is not meaningful, I have attached output pdf and original image which i want display on my pdf. please help for the same.
PDFBox doesn't support embedding CMYK images at all because java itself can't read such images. You might be able to embed it as an RGB image by using the twelvemonkeys library instead of Java ImageIO to read the JPEG into a BufferedImage. From there, just use PDPixelMap (in 1.8) or LosslessFactory (in 2.0).

How to set PIxelFormat to rgb in javafx?

With javafx, when I read images the PixelFormat is rgb and I want to apply filters on them.I use writableImage.pixelWriter to set the pixels color but the PixelFormat is rgba.
I use ImageIO.write() and it work for .png, but when I try to save this modified image in .jpg or .jpeg, the color change. I find that's because rgba don't work with jpg but i don't know how to change this PixelFormat.
Is there a way to change rgba format in rgb ? Do you know another way to save javafx Image as .jpg/.jpeg ?
Edit : How I save file (it works for png)
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("JPG Files", "*.jpg"));
File outputFile = fileChooser.showSaveDialog(null);
BufferedImage bImage = SwingFXUtils.fromFXImage(modifiedImage.getImage(), null); // getImage() return a javafx.scene.image.Image;
try {
ImageIO.write(bImage, "jpg", outputFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
How I modify image (example)
Image currentImage = modifiedImage.getImage();
WritableImage writableImage = new WritableImage((int) currentImage.getWidth(), (int) currentImage.getHeight());
PixelReader pixelReader = currentImage.getPixelReader();
PixelWriter pixelWriter = writableImage.getPixelWriter();
for (int i = 0; i < (int) currentImage.getWidth(); i++) {
for (int j = 0; j < (int) currentImage.getHeight(); j++) {
pixelWriter.setColor(i, j, new Color(0,0,0,1));
}
}
modifiedImage.setImage(writableImage);
When I get the PixelFormat of the reader it's rgb but for the writer it's rgba. If I save an image without modification it's good, but when I apply a filter on it and I save the image as jpg, the colors change.
On my app the colors are good but if I open the jpg file outside they aren't. With png files there is no problem. I can allow to save only as png but it would be better if i can choose.
Solution :
BufferedImage bImage = SwingFXUtils.fromFXImage(modifiedImage.getImage(), null);
BufferedImage bImage2 = new BufferedImage(bImage.getWidth(), bImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
bImage2.getGraphics().drawImage(bImage, 0, 0, null);
try {
ImageIO.write(bImage2, "jpg", outputFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
You are again one of the many people who are hit by this bug https://bugs.openjdk.java.net/browse/JDK-8119048 which is not considered important enough to be fixed. If you read the comments in there you will find a work-arround. Basically the idea is to copy the image after the conversion into a new image without alpha channel.
I'd really like to know how many more people have to waste their time until this bug finally gets enough attention to be fixed.

JAVA : How to create .PNG image from a byte[]?

I have seen some code source, but I do not understand...
I use Java 7
Please, how to convert a RGB (Red,Green,Blue) Byte Array (or something similar) to a .PNG file format ?
Example from an array that could represent "a RGB pixel" :
byte[] aByteArray={0xa,0x2,0xf};
Important Aspect :
I try to generate a .PNG file only from a byte[] "not from a previous existing file"
is it possible with an existing API? ;)
Here my first code :
byte[] aByteArray={0xa,0x2,0xf};
ByteArrayInputStream bais = new ByteArrayInputStream(aByteArray);
File outputfile = new File("image.png");
ImageIO.write(bais, "png", outputfile);
....Error : No suitable Method Found
Here the other version modified from Jeremy but look similar :
byte[] aByteArray={0xa,0x2,0xf};
ByteArrayInputStream bais = new ByteArrayInputStream(aByteArray);
final BufferedImage bufferedImage = ImageIO.read(newByteArrayInputStream(aByteArray));
ImageIO.write(bufferedImage, "png", new File("image.png"));
....multiple Errors : image == null! ...... Sure ? Note : I do not search to use a source file
The Image I/O API deals with images, so you need to make an image from your byte array first before you write it out.
byte[] aByteArray = {0xa,0x2,0xf,(byte)0xff,(byte)0xff,(byte)0xff};
int width = 1;
int height = 2;
DataBuffer buffer = new DataBufferByte(aByteArray, aByteArray.length);
//3 bytes per pixel: red, green, blue
WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, 3 * width, 3, new int[] {0, 1, 2}, (Point)null);
ColorModel cm = new ComponentColorModel(ColorModel.getRGBdefault().getColorSpace(), false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
BufferedImage image = new BufferedImage(cm, raster, true, null);
ImageIO.write(image, "png", new File("image.png"));
This assumes the byte array has three bytes per pixel (red, green then blue) and the range of values is 0-255.

Convert and display image from byte array

I'm making a program, which gets data about an image in byte array from a server. I'm converting this data into 24bit BMP format (whether its jpeg, png, bmp or 8-24-32bpp). First, I'm saving it to my HD, and then I'm loading it into a JLabel's Icon. Works perfectly, though there are some cases in which I get the following exception:
java.io.EOFException at
javax.imageio.stream.ImageInputStreamImpl.readFully(ImageInputStreamImpl.java:353) at
com.sun.imageio.plugins.bmp.BMPImageReader.read24Bit(BMPImageReader.java:1188) at
com.sun.imageio.plugins.bmp.BMPImageReader.read(BMPImageReader.java:843) at
javax.imageio.ImageIO.read(ImageIO.java:1448) at
javax.imageio.ImageIO.read(ImageIO.java:1308)
For this line (the second)
File imgFile = new File("d:/image.bmp");
BufferedImage image = ImageIO.read(imgFile);
In these cases:
the image does not load into the JLabel, but it can be found on my HD
the conversion is not proper, because something "slips"
the picture is like when you use italics in a word document
First, i thought maybe the bpp is the problem, then i thought that maybe the pictures are too large, but i have cases it works and cases it doesn't for both suggestions. I'm a little stuck here, and would be glad for ideas.
the picture is like .. when You use italics in a word document
Think I finally got what this bullet item meant now.. ;-)
Speculative answer, but here goes:
If the image you write looks "skewed", it's probably due to missing padding for each column as the BMP format specifies (or incorrect width field in the BMP header). I assume then, that the images you get EOF exceptions for, is where the width is not a multiple of 4.
Try to write the BMPs using ImageIO to see if that helps:
private static BufferedImage createRGBImage(byte[] bytes, int width, int height) {
DataBufferByte buffer = new DataBufferByte(bytes, bytes.length);
ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[]{8, 8, 8}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
return new BufferedImage(cm, Raster.createInterleavedRaster(buffer, width, height, width * 3, 3, new int[]{0, 1, 2}, null), false, null);
}
...
byte[] bytes = ...; // Your image bytes
OutputStream stream = ...; // Your output
BufferedImage image = createRGBImage(bytes, width, height);
try {
ImageIO.write(image, "BMP", stream);
}
finally {
stream.close();
}
Call it by class name, liek ClassName.byteArrayToImage(byte):
public static BufferedImage byteArrayToImage(byte[] bytes){
BufferedImage bufferedImage=null;
try {
InputStream inputStream = new ByteArrayInputStream(bytes);
bufferedImage = ImageIO.read(inputStream);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
return bufferedImage;
}
You can use this code to convert the output image to a byte Array
Blob b = rs.getBlob(2);
byte barr[] = new byte[(int)b.length()]; //create empty array
barr = b.getBytes(1,(int)b.length());
FileOutputStream fout = new FileOutputStream("D:\\sonoo.jpg");
fout.write(barr);

Categories