Java JAI BufferedImage versus C++ OpenCV Mat imread? - java

In Java:
I am reading an image using JAI:
BufferedImage image = javax.imageio.ImageIO.read(new File("path to JPG image"));
Then, I look at the rgb value of the pixel (0,2):
System.out.println("pixel[0][2]="+(new Color(image.getRGB(2, 0))));
In C++ OpenCV:
Mat image = imread("path to the same JPG image");
image.convertTo(image, CV_32S);
cout <<" r value of pixel[0][2] "<< image.at<Vec3i>(0, 2)[2] << "\n";
The values are different: r value in Java is 156 and in C++ is 155. Why?

I think this has to do with the format of the image, not with Java or OpenCV. JPEG is lossy compression, so when decoding the data you may get different outputs for the same image. That will depend on the decoder you are using to read the image information. The issue you are experimenting is similar to the one described in the below question.
Reading jpg file in OpenCV vs C# Bitmap

Related

Reading and Writing CMYK TIFF in Java 9

My goal here is to read in a CMYK Tiff image, mess with the pixels and then write out a new CMYK Tiff image. I am having a tough time finding any kind of example for this and any help would be greatly appreciated. Originally, I was doing this with RGB JPEG images without a problem using code like this:
// read input image
BufferedImage in = ImageIO.read(inputJPGAsFile);
// made output image that is same size as input image
FinalImage = new BufferedImage(in.getWidth(), in.getHeight(), BufferedImage.TYPE_INT_ARGB);
// mess with pixels in output image
// write as JPG
ImageIO.write(FinalImage, "JPEG", outputJPGAsFile);
However, now I am trying to figure out how to change this to work with CMYK Tiffs. It doesn't seem like there is a type for BufferedImage that would be anything like "TYPE_INT_CMYK". So then I was trying to use the ColorModel of the input image, but this crashes with the following error Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Unknown color space. Any help on this would be greatly appreciated.
// read input image
BufferedImage in = ImageIO.read(inputTiffAsFile);
// get the CMYK color space of input image
ColorModel colorModel = in.getColorModel();
BufferedImage FinalImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(100, 100), colorModel.isAlphaPremultiplied(), null);
// Copy in to FinalImage with some pixel manipulation
// write final image
ImageIO.write(FinalImage, "TIFF", outputTiffAsFile);
Also, I put java 9 because that is what I have been using, but I can upgrade to a newer version if that makes things easier. Thanks!

Dealing with Adobe CMYK jpegs and Bufferedimage in java

Im trying to apply the code posted in this post:
How to convert from CMYK to RGB in Java correctly?
The Answer from the guy named Codo works for me so far, but my source is not a file, its an object that gets converted into a BufferedImage with
stream = (PRStream)object;
PdfImageObject image = new PdfImageObject(stream);
//this does not work
BufferedImage bi = image.getBufferedImage();
The guy has a method that returns a BufferedImage from a file like so
public BufferedImage readImage(File file) throws IOException, ImageReadException
but i want to use
BufferedImage bi = readImage(image.getBufferedImage());
instead of
File f = new File("/Users/adlib/Documents/projekte/pdf_compress/envirement/eclipse_luna/WORKSPACE/PDFCompression/src/Bild.jpg");
BufferedImage bi = readImage(f);
cause im ectracting all the images from a pdf file using iText.
I messed around with the code (changed file to BufferedImage and added streams) but a just dont get it to work. The File as Input image works fine, but not really what i need. What do i need to change to get This guys code to work with BufferedImage as input for the readImage() method?
Here is the complete code of this guy
https://stackoverflow.com/a/12132630/4944643
He uses Sanselan / Apache Commons Imaging
I'm not sure how iText extracts images, but chances are good it's using ImageIO. If so, you can just install (or depend on, using Maven) the TwelveMonkeys JPEG ImageIO plugin, and
BufferedImage bi = image.getBufferedImage();
...should just work.
The above mentioned plugin does support CMYK (and Adobe YCCK) JPEGs.
If iText doesn't use ImageIO, the above won't work (ie. when you already have a BufferedImage, it's too late to make the correct conversion). You will instead need to get to the bytes of the underlying PDF (using the getImageAsBytes() method), and use ImageIO (via the TwelveMonkeys JPEG plugin) to decode it:
byte[] imgBytes = image.getImageAsBytes();
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(imgBytes));

Update Tiff-Metadata using Apache Commons-Imaging/Sanselan

I will modify and add Tiff-Tags to existing tif-files with java. JAI imageio crashed, because it could not deal with certain tags from Tiff 6.0. Apache Commons-Imaging seems to be able to deal with these tags. But I have no idea, how to do that. I found a post here, I used for beginning (How to embed ICC_Profile in TiffOutputSet).
Using the example code creates an image, which I can't open because of an LZW error. If I use the Imaging.writeImage(...) methods, It changes the color model from 8Bit to 24Bit and the Exif metadata hase gone.
What i have done is:
bufferedImage = Imaging.getBufferedImage(srcTiff);
byte[] imageBytes = Imaging.writeImageToBytes(tifFile, imageFormat, optional_params)
exifDirectory = tiffOutputSet.getOrCreateRootDirectory();
...
TiffImageWriterLossLess lossLessWriter = new TiffImageWriterLossless(imageBytes);
os = new FileOutputStream(tmpFile);
os = new BufferedOutputStream(os);
lossLessWriter.writeImage(bufferedImage, os, image_params);
Playing around with image_params, like compression or defining the outputset as params, results in different issues. But one is constant, the destImage is bigger then the src image, even when the source image is 24 bit like the dest image.
How could I get Commons-Imaging work for me?
I can respond to the destImage bigger than the src, it is because TIFF images have a compression that is not carried over when the image is read into memory. On writing the image back to storage, you must apply the compression explicitly.

Load Image OpenCV (JavaCV) from byte[] not a file

I have image data coming in from over a socket connection as a byte[]. All examples I have seen using cvLoadImage() is passed a file name. Do I have to save every image to file and re-open it to do the processing? This seems to have a lot of overhead for what needs to happen, is it possible to load the image from the byte[] data?
Simple solution in the end, you can use the following method to create an Image from a BufferedImage which solved my problem:
IplImage src = IplImage.createFrom(buffered);
Assuming the data is encoded in some standard format like JPG or PNG, and assuming you are using JavaCV, for a byte array b, this works as well:
IplImage image = cvDecodeImage(cvMat(1, b.length, CV_8UC1, new BytePointer(b)));

How can i convert *.raw files to *.bmp in JAVA?

BufferedImage image = ImageIO.read( new ByteArrayInputStream( byteArray ) );
ImageIO.write(image, "BMP", new File("filename.bmp"));
When i tried this thing [ImageIO.read( new ByteArrayInputStream( byteArray ))] returns null value so i cant create new bmp file.
But this works to convert jpg to bmp files.I have raw files and i need to convert to image.
Please help me in this.
The support for readers and writers in the javax.imageio is limited, and if you dont know the format of the byte[] your are trying to convert, then propably it is not included in the list of valid image readers. Then, what you might need is the Java Advanced Imaging API, which you can find here.
These are the readers a
Readers: Writers:
bmp bmp
jpg jpg
jpeg jpeg
wbmp Wbmp
png png
gif gif
This few lines shall help you to get this to work using JAI API
// read byte[]
SeekableStream stream = new ByteArraySeekableStream(image);
// render stream of bytes to valid image format
RenderedImage renderedImage = JAI.create("stream", stream);
// persist image to file
JAI.create("filestore", renderedImage, filename, targetFormat);
// dont't forget to close the stream!
stream.close();
Take a look here: Java Advanced Imaging I/O Tools. The Java Image I/O Reader seems to be able to read "raw"-Files. I think that you can write them with the Java Image I/O Writer as BMP.
regards
Macs

Categories

Resources