使用ImageIO.write保存文件(JPG)时处理java.awt.Color

时间:2015-11-20 22:28:13

标签: java colors

参加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)我能做些什么来使这段代码有效?

非常感谢!

1 个答案:

答案 0 :(得分:1)

JPEG具有有损压缩,这意味着在重新加载图像时会有效地修改某些像素。这不是ImageIO.write的错误,它的格式是如何工作的。如果要将数据直接嵌入像素值,则需要将图像保存为无损格式,例如BMP或PNG。