参加Coursera课程,我一直试图用steganography隐藏另一个图像。这意味着我试图在6位上存储“主”图像的RGB值,在最后2位上存储“第二”图像的值。 我正在合并这两个值以创建一个联合图片,并且还编写了一个类来解析联合图片,并恢复原始图像。
图像恢复还没有成功,虽然看起来(从课程中提供的其他示例)解析器工作正常。我想在修改后保存图片,使用ImageIO.write以某种方式修改我在代码中仔细设置的RGB值。 :d
public static BufferedImage mergeImage(BufferedImage original,
BufferedImage message, int hide) {
// hidden is the num of bits on which the second image is hidden
if (original != null) {
int width = original.getWidth();
int height = original.getHeight();
BufferedImage output = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int pix_orig = original.getRGB(i, j);
int pix_msg = message.getRGB(i, j);
int pixel = setpixel(pix_orig, pix_msg, hide);
output.setRGB(i, j, pixel);
}
}
return output;
}
return null;
}
public static int setpixel(int pixel_orig, int pixel_msg, int hide) {
int bits = (int) Math.pow(2, hide);
Color orig = new Color(pixel_orig);
Color msg = new Color(pixel_msg);
int red = ((orig.getRed() / bits) * bits); //+ (msg.getRed() / (256/bits));
if (red % 4 != 0){
counter+=1;
}
int green = ((orig.getGreen() / bits) * bits) + (msg.getGreen() / (256/bits));
int blue = ((orig.getBlue() / bits) * bits) + (msg.getBlue() / (256/bits));
int pixel = new Color(red, green, blue).getRGB();
return pixel;
}
这是我用来设置合并图片的RGB值的代码。正如您所看到的,我已经评论了属于红色的部分代码,以检查主图片是否可以实际保存在6位上,假设我采用
int hide=2虽然如果我在代码的解析部分进行相同的检查:
public static BufferedImage parseImage(BufferedImage input, int hidden){
// hidden is the num of bits on which the second image is hidden
if (input != null){
int width = input.getWidth();
int height = input.getHeight();
BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for(int i=0;i<width;i++){
for(int j=0;j<height;j++){
int pixel = input.getRGB(i, j);
pixel = setpixel(pixel,hidden);
output.setRGB(i, j, pixel);
}
}
return output;
}
return null;
}
public static int setpixel(int pixel, int hidden){
int bits = (int) Math.pow(2,hidden);
Color c = new Color(pixel);
if (c.getRed() % 4 != 0){
counter+=1;
}
int red = (c.getRed() - (c.getRed()/bits)*bits)*(256/bits);
int green = (c.getGreen() - (c.getGreen()/bits)*bits)*(256/bits);
int blue = (c.getBlue() - (c.getBlue()/bits)*bits)*(256/bits);
pixel = new Color(red,green,blue).getRGB();
return pixel;
}
我得到~100k像素,其中R值除以4时得到余数。 我怀疑ImageIO.write的功能有些问题。 我知道这个问题会模糊不清,但是 1)有人可以证实这一点 2)我能做些什么来使这段代码有效?
非常感谢!
答案 0 :(得分:1)
JPEG具有有损压缩,这意味着在重新加载图像时会有效地修改某些像素。这不是ImageIO.write
的错误,它的格式是如何工作的。如果要将数据直接嵌入像素值,则需要将图像保存为无损格式,例如BMP或PNG。