0

I have to save a jpeg image lossless. I am work on a steganography project but Java compressing and saving my result. I research every forums and try everything but it didn't work.

Here my example code for lossless save a jpeg image:

BufferedImage image = ImageIO.read(new File("sources/image.jpg"));

ImageWriter writer = ImageIO.getImageWritersByFormatName("JPEG").next();
JPEGImageWriteParam jpegParams = new JPEGImageWriteParam(null);

jpegParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(1f);

writer.setOutput(ImageIO.createImageOutputStream(new File("example.jpg")));
writer.write(null, new IIOImage(image,null,null), jpegParams);
writer.dispose();

After this process I compute PSNR value is 28.53173 and "example.jpg"'s size is bigger than "image.jpg".

I try import JAI library but I am not sure Java 8 is support JAI.

nbrooks
  • 18,126
  • 5
  • 54
  • 66
vakkaya
  • 31
  • 1
  • 1
  • 6
  • Can you share more details of your algorithm so we can understand why your jpeg has to be lossless? It might turn out that jpeg isn't the right format for your algorithm, or that you have to encode your stego image in a specific way. Read [here](https://stackoverflow.com/questions/29677726/steganography-in-lossy-compression-java/29678676#29678676) for an example. – Reti43 Oct 22 '16 at 10:55
  • Firstly thanks for your answer. My algorithm is very simple. Text/image message to binary, read the cover image, RGB to YCbCr, seperate 8x8 blocks for Y space, DCT for every blocks, and than setting medium frequency's max coefficient's LSB. After all IDCT, YCbCr to RGB and save. I have to do that in Android application and have to read JPEG write JPEG. – vakkaya Oct 22 '16 at 12:11
  • 1
    Did you base your algorithm from some publication which you can show us? If you're reading a JPEG, you don't have to reconstruct the pixels from the file data. Just load the DCT blocks in the memory, modify them per your algorithm and then reencode them to the output file. That way you avoid all the lossy stuff of the JPEG format, which involves the transform and quantisation steps. – Reti43 Oct 22 '16 at 14:07
  • I suspect parts of [this answer](http://stackoverflow.com/a/35398127/2243104) are relevant to your needs, especially the pseudocode concepts. If this answers your question, let me know so I can update my answer. – Reti43 Oct 22 '16 at 14:43
  • I read your answer and your steps. I am already loading DCT blocks in memory and write dct blocks new empty image or copied original image. When i save the modified BufferedImage object, the output image size is smaller than original image. I decode the output image and seeing nothing. All values are changed. In my opinion, Java compress and save my modified image. So i lost my hidden data. I want to no compress. I can publish my code with you if you want. – vakkaya Oct 23 '16 at 13:42
  • This sounds like a follow up issue to the topic discussed here and you should [ask a new question](https://stackoverflow.com/questions/ask) instead. – Reti43 Oct 23 '16 at 14:27
  • Hey @Reti43 i have create a new [question](http://stackoverflow.com/questions/40241441/is-there-anyone-used-jai-for-read-write-jpeg). Can you check that ? – vakkaya Oct 25 '16 at 16:16

1 Answers1

3

JPEG is lossy all the time. Even at 100% compression quality there will be some loss of information, but it will be minimised.

The reason why your example.jpg has a bigger size is because it was encoded with a 100% quality factor, while most jpeg encoders have a default value of 50%-75%, which is what was most likely used for example.jpg. You can try different quality factors to see when both files have the same size.

A lossless JPEG format does exist (available in JAI), but it should be thought of as a different format to the conventional JPEG. However, it's not widely used and you'll probably not be able to view it in most applications, which would practically defeat the point of sharing an innocent image.

Reti43
  • 9,656
  • 3
  • 28
  • 44