0

I am currently doing project related to "image steganography" in Java, for that I want to compress and decompress the secret image. I have done the compression part. But I don't know how to perform the decompression part.

I have compressed the JPEG image using the following code:

public class CompressJPEGFile {

    public static void main(String[] args) throws IOException {

        File imageFile = new File("C:\\Users\\user\\Desktop\\encryption\\d.jpg");

        File compressedImageFile = new File("C:\\Users\\user\\Desktop\\encryption\\compress.jpg");

        InputStream is = new FileInputStream(imageFile);

        OutputStream os = new FileOutputStream(compressedImageFile);

        float quality = 0.5f;

        BufferedImage image = ImageIO.read(is);

        // get all image writers for JPG format

        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");

        if (!writers.hasNext())

            throw new IllegalStateException("No writers found");

        ImageWriter writer = (ImageWriter) writers.next();

        ImageOutputStream ios = ImageIO.createImageOutputStream(os);

        writer.setOutput(ios);

        ImageWriteParam param = writer.getDefaultWriteParam();

        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);

        param.setCompressionQuality(quality);



        //associated stream and image metadata and thumbnails to the output

        writer.write(null, new IIOImage(image, null, null), param);

        // close all streams

        is.close();

        os.close();

        ios.close();

        writer.dispose();

    }
}

I have written the code for decompression. Is the code right if I am not considering the quality of image?

 public static void decompress() throws FileNotFoundException {
        try {

            File compressedImageFile = new File("C:\\Users\\user\\Desktop\\encryption\\compressnew.jpg");
             File imageFile = new File("C:\\Users\\user\\Desktop\\encryption\\dnew.jpg");


            InputStream is = new FileInputStream(compressedImageFile);

            OutputStream os = new FileOutputStream(imageFile );

            BufferedImage image = ImageIO.read(is);

            // get all image writers for JPG format

            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");

            if (!writers.hasNext()) {
                throw new IllegalStateException("No writers found");
            }

            ImageWriter writer = (ImageWriter) writers.next();

            ImageOutputStream ios = ImageIO.createImageOutputStream(os);

            writer.setOutput(ios);

            ImageWriteParam param = writer.getDefaultWriteParam();

            writer.write(null, new IIOImage(image, null, null), param);

            //associated stream and image metadata and thumbnails to the output

            is.close();

            os.close();

            ios.close();

            writer.dispose();
        } catch (IOException ex) {
            Logger.getLogger(CompressJPEGFile.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
halfer
  • 19,824
  • 17
  • 99
  • 186
  • What do you mean *decompressing* the image ?If it means revert back to the original quality, forget it. JPG is a loss compression type, there is no way to retrieve the original quality. – ortis Dec 18 '14 at 10:09
  • then how can i perform the task?is there any way to retrieve the image with less quality? – user3831796 Dec 18 '14 at 10:17
  • Your code is already generating an image with less quality. What are you trying to achieve here ? – ortis Dec 18 '14 at 10:29
  • i am performing image steganography .secret image is compressed first and then embedded with the cover image.At the receiver side i want to decompress it to retrieve the original secret. is there any library available for that purpose? – user3831796 Dec 18 '14 at 10:35
  • Let me google that for you. java steganography library. Returns, e.g. Hide and Reveal (http://hidereveal.ncottin.net/) - a GPL Java steganography library. – J Richard Snape Dec 18 '14 at 10:37
  • Sorry i dont need library for steganography.I need it for image compression and decompression. – user3831796 Dec 18 '14 at 10:40
  • can i get code for decompressing image if quality doesn't matters? – user3831796 Dec 18 '14 at 10:46
  • What do you mean code for decompressing an image? Your compression code is resaving an image to jpeg in some low quality. That should, most likely, result to fewer bytes in the resaved image than the original. You don't need to do any decompression yourself, an image viewer, or i/o can read this compressed, lower quality image for you. But you cannot retrieve the bytes of the original from the resaved image because your compression was lossy. Richard explains that in his answer. – Reti43 Dec 18 '14 at 11:31

1 Answers1

2

I think you are looking for a lossless a compression scheme that is such that you can retrieve a secret from steganography. That means you need to move away from jpg as your compression format - it is lossy. That means that once you have put your secret + cover image through the jpg compression, the original cannot be recovered by a simple 'decompression' call at the other end, i.e. the JPEG compression algorithm is not reversible.

You ask in comments about libraries for compression / decompression rather than steganography. You are already using one in your code example (ImageIO). If you want to take your original image and transcode it to PNG (i.e. lossless compression), ImageIO can do that simply - see this question for details. JAI is commonly used if you need more advanced features. The PNG format offers a lossless compression option.

EDIT:

some code to show using ImageIO using PNG format as requested by OP in comments. By default ImageIO uses compression when you write PNG's. At the receive end, simply read the PNG, you get the original back.:

public class JPEGFileToPNG {

public static void main(String[] args) throws IOException {

    File imageFile = new File("C:\\Users\\user\\Desktop\\encryption\\d.jpg");
    File compressedImageFile = new File("C:\\Users\\user\\Desktop\\encryption\\compress.png");

    BufferedImage image = ImageIO.read(imageFile.toURI().toURL());

    ImageIO.write(image, "png", compressedImageFile);

}

P.S. There are two levels at which to answer your question. At the more advanced (maybe research) level - people do work on using the actual errors introduced by JPG encoding to encode the secret in steganography (e.g. http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1357167&tag=1) From the wording of your question, I don't think this is what you want, but it might be. In which case, your task is quite hard (writing a JPEG encoder / decoder and adapting it to hide secrets in the encoding table), but it has been done (e.g. this paper describes the method).

Community
  • 1
  • 1
J Richard Snape
  • 20,116
  • 5
  • 51
  • 79
  • How can i compress and decompress png files?can you please tell me where can i get the code or any resources?By using JAI can i get decompressed image of jpeg? – user3831796 Dec 18 '14 at 11:16
  • I think you may be misunderstanding. Once you have compressed the JPEG using quality = 0.5 **you can never get the original back**. Of course you can view the new more compressed image and it will still look a bit like the original, just lower quality. But the full information contained in the original is irretrievably lost. I've edited my question to give a code snippet to show using PNG as the format. – J Richard Snape Dec 18 '14 at 11:59
  • ok now i understood.sorry if i am annoying you by asking the same question again,but if i compress with quality=0.9 i will get much more better data by decompressing it right?if i dont think about quality where can i get the code for decompressing jpg? – user3831796 Dec 19 '14 at 06:19
  • I have edited my question with a decompression code.please go through it and check whether it is correct or not – user3831796 Dec 19 '14 at 07:29
  • Don't worry - you are not annoying me. I see the moderators have put the question on hold. The problem is that the questions you are asking are revealing a misunderstanding of the underlying technology. I think you need to go back to whoever set you the task and ask for some direction. Or, if it's your own task, understand what JPEG encoding/decoding does before you try to add steganography. Stackoverflow isn't the best forum for this. I don't think I can help more, sorry. – J Richard Snape Dec 19 '14 at 12:28
  • This is an old question, but I thought I'd add a quick comment to highlight an area that might have caused confusion, for the benefit of new users. The OP has not made it clear where they are experiencing lossiness - is it by virtue of the JPEG algorithm or their stenographic method? I don't know how the latter works (and the method in this case is not explained) but would be willing to believe this could introduce non-reversible error as well. – halfer Nov 12 '15 at 08:16