如何解压缩使用速记法存储的图像?

时间:2014-12-18 10:00:17

标签: java image image-processing compression image-compression

我目前正在做与"图像隐写相关的项目"在Java中,为此我想压缩和解压缩秘密图像。我做了压缩部分。但我不知道如何执行减压部分。

我使用以下代码压缩了JPEG图像:

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();

    }
}

我已经编写了解压缩代码。如果我不考虑图像的质量,代码是否正确?

 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);
        }

    }

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找一种lossless压缩方案,以便您可以从隐写术中检索秘密。这意味着您需要远离jpg作为压缩格式 - 它是lossy。这意味着一旦你通过jpg压缩你的秘密+封面图像,原来无法通过另一端的简单“解压缩”调用恢复,即JPEG压缩算法是不可逆的。

您在评论中询问压缩/解压缩库而不是隐写术。您已经在代码示例(ImageIO)中使用了一个。如果您想拍摄原始图像并将其转码为PNG(即无损压缩),ImageIO可以做到这一点 - 有关详细信息,请参阅this question。如果您需要更多高级功能,则通常会使用JAI。 PNG格式提供无损压缩选项。

编辑:

根据评论中OP的要求,使用PNG格式使用ImageIO显示的一些代码。默认情况下,ImageIO在您编写PNG时使用压缩。在接收端,只需阅读PNG,即可获得原始版本。:

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。有两个级别可以回答您的问题。在更高级(可能是研究)级别 - 人们确实使用JPG编码引入的实际错误来编码隐写中的秘密(例如http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1357167&tag=1)从问题的措辞来看,我认为这不是你想要什么,但它可能是。在这种情况下,您的任务非常困难(编写JPEG编码器/解码器并对其进行修改以隐藏编码表中的秘密),但已完成(例如this paper describes the method)。