简体   繁体   English

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

[英]Handling of java.awt.Color while saving file (JPG) with ImageIO.write

Taking part in a Coursera course, I've been trying to use steganography to hide an image in another. 参加Coursera课程时,我一直在尝试使用隐写术将图像隐藏在另一个图像中。 This means I've tried to store the "main" picture's RGB values on 6 bits and the "second" picture's values on the last 2 bits. 这意味着我尝试将“主”图片的RGB值存储在6位上,将“第二”图片的值存储在最后2位上。 I'm merging these two values to create a joint picture, and have also coded a class to parse the joint picture, and recover the original images. 我将这两个值合并以创建一个联合图片,并且还对一个类进行了编码以解析联合图片并恢复原始图像。

Image recovery has not been successful, although it seems (from other examples provided within the course) that the parser is working fine. 尽管从解析器提供的其他示例来看,解析器工作正常,但是图像恢复并未成功。 I suppose that saving the pictures after modification, using ImageIO.write somehow modifies the RGB values I have carefully set in the code. 我想修改后保存图片,使用ImageIO.write可以修改我在代码中仔细设置的RGB值。 :D :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;
}

This is the code I use for setting the RGB values of the merged picture. 这是我用于设置合并图片的RGB值的代码。 As you can see, I have commented part of the code belonging to red to check whether the main picture can actually be saved on 6 bits, assuming I take 如您所见,假设我采取了以下措施,我已经注释了属于红色的代码的一部分,以检查主图像是否实际上可以保存为6位

int hide=2
Although if I make the same checks in the parsing part of the code: 尽管如果我在代码的解析部分中进行了相同的检查:

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

I get ~100k pixels where the R value has a remainder if divided by four. 我得到〜100k像素,如果R值除以四,则R值会有余数。 I suspect there' some problem with the function of ImageIO.write. 我怀疑ImageIO.write的功能存在问题。 I know the question is going to be vague, but 1) Can someone confirm this 2) What can I do to get this code working? 我知道问题将会变得很模糊,但是1)有人可以确认这一点2)我可以怎么做才能使此代码正常工作?

Thanks a lot! 非常感谢!

JPEG has lossy compression, which means some pixels will effectively be modified when reloading the image. JPEG压缩有损,这意味着在重新加载图像时会有效地修改某些像素。 This isn't a fault of ImageIO.write , it's how the format works. 这不是ImageIO.write的错误,而是格式的工作方式。 If you want to embed your data directly to pixel values, you want to save the image to a lossless format, such as BMP or PNG. 如果要直接将数据嵌入像素值,则需要将图像保存为无损格式,例如BMP或PNG。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM