Working with JPEG images in Java - java

I am using the BufferedImage class to read in an image as pixels which I then use bit shifting to get their appropriate components into separate int arrays. This works OK.
I have used this reference site to manually perform DCT functions with the pixel arrays.
Methods used: forwardDCT(), quantitizeMatrix(), dequantitzeMatrax(), inverseDCT()
which then are fed back into a resultant image array to reconstruct the JPEG file, which I then use BufferedImage's write() method to write the pixel data back out as the image.
This works perfectly, and I can view the image. (Even better the value I use to compress visually works).
My question is, is there a way to write the quantitize coefficients as the compressed values as a JPEG?
Because the BufferedImage write() method is used to input pixel data, rather than coefficient data?
Hope this is clear.
Thanks

Ultimately the DCT calculation is just one step in the whole JPEG encoding process. A complete implementation also has to deal with quantization, Huffman encoding, and conforming with the JPEG standard.
Java effectively just gives you an interface to a JPEG encoder that lets you do useful things like save images.
The ImageWriter that ImageIO.write() uses for JPEG images depends on your system. The default ImageWriter for JPEGs will only let you change some settings that affect the quantization and encoding using the JPEGImageWriteParam class (http://docs.oracle.com/javase/6/docs/api/javax/imageio/ImageWriteParam.html).
Getting your hand-crafted DCT coefficients into a JPEG file could potentially involve writing an entire JPEG library. If you don't want to do all that work, then you could modify the source of an existing library so that it uses your DCT coefficients.

Before the DCT . . .
While JPEG has no knowledge of colors, it is normal for JPEG file formats to use the YCbCr color space. If you are thinking about writing a JPEG file, you would need to do this conversion first.
After the Quantization . . .
The coefficients are run length encoded. That's a step you'd have to add. That's the most complex part of JPEG encoding.

Related

How to save jpeg image after replacing LSB in DCT with the Jsteg method?

I am using the Jsteg method, but i have a confusion, something i don't quite understand.The steps are:
Get 8x8 pixel block
Discret cosine tranform
Quantization
Replace the Least Significant Bit
What i don't understand is, when i open the image in java using BufferedImage and ImageIO and do these steps, how do i save the changes? if i write:
ImageIO.write(img,"jpg",new_img);
does java recompress the image and then the hidden text is lost, or when it does the compression it doesn't change anything since i did compress manually?
or should i save it in another way?
Bottom line:After replacing LSB, how to save the encoded image ?

Using Java in Google App Engine, how do I make a BMP image from an array of arrays of int r, g, b values?

What I have is: for each of the colors r, g and b, a two-dimensional array of integers in the [0,255] range. What I want is: create a BMP out of this array and send it to the client. The problem is, I cannot use java.awt.Color, BufferedImage, etc., since these are off-limits in the App Engine. The App Engine does offer an image manipulation service which, however, is meant for images I already have, not for creating images from scratch.
I am considering teaching myself how to 'manually' create a BMP, but this does seem like a lot of work. Should I do this, or is there an easier way?
The BMP format is pretty simple compared to JPG or PNG for example.
It has lots of header fields and bits, but you don't need to calculate/fill all. Basically what you need to do is create/write the BMP header which is less than 100 bytes (~56 if I remember well). Only a few fields you need to set, e.g. image size in pixels, image type (e.g. bits/bytes per pixel) etc. You can use the image type which is identical to yours: 3 bytes per pixel (r, g and b components).
Once you have this, the image data follows which you can just write as you have, one thing to keep in mind is that BMP stores images upside-down, and it may have line padding to be a multiple of 4 bytes for example.
That's all! Note that I haven't mentioned java.awt.Image or java.awt.Color because they are not needed to create simple BMPs.
I consider posting full code out of "scope" as you haven't posted any.
Here's an example Java implementation, use it or modify/tweak it to your needs:
http://www.javaworld.com/article/2077561/learn-java/java-tip-60--saving-bitmap-files-in-java.html
There are also many other Java implementations, don't be afraid to search.

Converting Pixel Array to Image in Java

I have used this code to get Image into array of pixels.
convertTo2DWithoutUsingGetRGB method for reading image to pixel array
writeToFile method for pixel array to image
Now I would like to convert the array of pixels to Image. But when I convert it, I am losing image data.
Initial Image size: 80Kb JPG
Duplicate Image size: 71Kb JPG
I can clearly notice some difference between the both images, the Java produced image has some sort of white-noise.
I would like to reproduce the image without single pixel loss of data, how do I achieve in Java?
The jpg file format uses a lossy compression algorithm which means that the files it generates will have slight differences from the original. You can change the quality setting to compress more or less but you can't save the with its original size without any modifications.
This is why jpg isn't recommended for image editing. Use a lossless format instead, like PNG.

How to get a better understanding of a png representation on java?

I want to dive in the low level of how a png file is represented on memory in java, so that i can iterate over its pixels, change them, create a modified png file using existing one, etc.
Where do i begin?
You could begin by reading it into a BufferedImage with ImageIO.read(file) .
The getRGB(...) methods can help you to obtain information about the individual pixels, and the corresponding setRGB(...) methods help you to change them.
The representation of an image in memory in Java, is essentially unrelated to the format of the file: be it PNG, JPEG, GIF or whatever, those are standards for encoding an image as a (language independent) stream of bytes. But when you are manipulating the pixels of an image in memory, you have already decoded it, and so you've "forgotten" from which format (PNG, JPEG...) it came from.
The most common way of manipulating an image in Java is using the BufferedImage class, included in the java.awt.image.* package. But that's not a requisite. For instance, I've worked on a low level PNG coder/encoder (PNGJ) that does not use BufferedImage, but instead gives you each image line as an int[] array.

Read/write imag files by lines or by pixels using Java

I have a specific object with image data. And I want read/write images (in BMP, JPEG and PNG formats) to this object.
Of course, I can read/write image into/from BufferedImage and then copy/paste pixels into/from my object. But, I want to do it more faster without intermediate objects!
How can I perform it over standard Java library or throw other Java library?
P.S.:
I know pngj library that allow read PNG images by lines. Maybe you know same libraries for BMP, JPEG (or for all of them: BMP, JPEG, PNG)?
Why don't you just have the BufferedImage in your Object? BufferedImage isn't all that bad. Otherwise, you will need to use something like BufferedImage to convert the image file into pixels, and then read the BufferedImage into something like an int[] array of pixels, but it still requires BufferedImage in the middle, and this would slow things down by adding an extra loop to read over and store the pixels.
Is there a reason why BufferedImage isn't suitable for your purpose?
If you want to do all the reading by yourself, you can just open the file with a stream and read it into an array, but you would need to work your way through the whole structure of the file (headers etc...) if you are working with compressed formats you'd have to work on that too.
Best would be to use imageio to load/write your files and I don't believe there is a lot of overhead coming from the read/write of your images.
Also if you expect to do some heavy work on the images, know that BufferedImages can be hardware accelerated which will improve performance a lot.

Categories