我目前正在做与"图像隐写相关的项目"在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);
}
}
答案 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)。