【问题标题】:Handling of java.awt.Color while saving file (JPG) with ImageIO.write使用 ImageIO.write 保存文件 (JPG) 时处理 java.awt.Color
【发布时间】:2015-11-20 22:28:12
【问题描述】:

参加 Coursera 课程,我一直在尝试使用 steganography 将图像隐藏在另一个图像中。这意味着我尝试将“主”图片的 RGB 值存储在 6 位上,将“第二”图片的值存储在最后 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 值的代码。可以看到,我把属于red的部分代码注释掉了,看看主图是不是真的可以保存在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 值除以四时有余数。 我怀疑 ImageIO.write 的功能有问题。 我知道这个问题会很模糊,但是 1)有人可以证实这一点 2) 我该怎么做才能让这段代码正常工作?

非常感谢!

【问题讨论】:

    标签: java colors


    【解决方案1】:

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

    【讨论】:

    • 非常感谢,将所有内容切换到 BMP 已解决。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 2016-11-09
    相关资源
    最近更新 更多