当前位置: 首页 > 知识库问答 >
问题:

有没有办法将getRGB和setRGB与隐写术结合使用?

晏富
2023-03-14

我正在编写一个具有简单隐写实现的程序

我有一个问题,因为如果我对一个像素使用setRGB,然后使用getRGB,我会得到不同的值。我读到setRGB和getRGB不是字节和位运算的最佳方案,但也许有一种方法?我想使用每个像素的阿尔法红、绿、蓝的LSB,但我不知道如何使用光栅,老实说,我花了很多时间编写一些代码来生成适当的TYPE_INT_ARGB值。。。我想使用ARGB中的每2个LSB,所以我有8个像素位,这就为像素提供了一个字符。

System.out.println("ARGB in int befor edit: " + obraz.getRGB(0, 0));
    int RGB = obraz.getRGB(0, 0);
    int alpha = (RGB >> 24) & 0xFF;
    int red = (RGB >> 16) & 0xFF;
    int green = (RGB >> 8) & 0xFF;
    int blue = (RGB) & 0xFF;

   System.out.println("RGB: " + RGB);
   System.out.println("alpha: " + alpha);
   System.out.println("red: " + red); 
   System.out.println("green: " + green); 
   System.out.println("blue: " + blue);

   System.out.println("After:");
   int newARGB = addLetter(RGB, 'b'); //this change every two bits of ARGB
   int alpha2 = (newARGB >> 24) & 0xFF;
   int red2 = (newARGB >> 16) & 0xFF;
   int green2 = (newARGB >> 8) & 0xFF;
   int blue2 = (newARGB) & 0xFF;


obraz.setRGB(0,0,newRGB);

 System.out.println("ARGB in int after edition: " + obraz.getRGB(0, 0));
    int RGB3 = obraz.getRGB(0, 0);
    int alpha3 = (RGB3 >> 24) & 0xFF;
    int red3 = (RGB3 >> 16) & 0xFF;
    int green3 = (RGB3 >> 8) & 0xFF;
    int blue3 = (RGB3) & 0xFF;

   System.out.println("RGB: " + RGB3);
   System.out.println("alpha: " + alpha3);
   System.out.println("red: " + red3); 
   System.out.println("green: " + green3); 
   System.out.println("blue: " + blue3);

结果是不同的,所以隐写术不起作用。。。

这是addLetter函数

    public static int addLetter(int i, char letter)
{
    byte tym, tc;
    tc = (byte) letter;
    int ARGB;


    byte byte3 = (byte) ((i & 0xFF000000) >> 24);
    byte3 = (byte) (byte3 & (~0x00000003));
    tym = (byte) ((tc & 0xC0) >> 6);
    byte3 = (byte) (byte3 | tym);


    byte byte2 = (byte) ((i & 0x00FF0000) >> 16);
    byte2 = (byte) (byte2 & (~0x00000003));
    tym = (byte) ((tc & 0x30) >> 4);
    byte2 = (byte) (byte2 | tym);

    byte byte1 = (byte) ((i & 0x0000FF00) >> 8);
    byte1 = (byte) (byte1 & (~0x00000003));
    tym = (byte) ((tc & 0x0C) >> 2);
    byte1 = (byte) (byte1 | tym);

    byte byte0 = (byte) ((i & 0x000000FF));
    byte0 = (byte) (byte0 & (~0x00000003));
    tym = (byte) ((tc & 0x03));
    byte0 = (byte) (byte0 | tym);

    byte[] wynik = (new byte[]{byte3, byte2, byte1, byte0});
    return ByteBuffer.wrap(wynik).getInt();   

我将非常感谢任何帮助和理解。我还是爪哇的初学者

编辑:

我将再次尝试解释我的问题:我使用函数//int I-我将getRGB的结果传递给pixel//char letter-这是一个字母,我将其添加到a、R、G和B值公共静态int addLetter(int I,char letter){byte tym,tc;tc=(byte)letter;int ARGB;

    byte byte3 = (byte) ((i & 0xFF000000) >> 24);
    byte3 = (byte) (byte3 & (~0x00000003));
    tym = (byte) ((tc & 0xC0) >> 6);
    byte3 = (byte) (byte3 | tym);


    byte byte2 = (byte) ((i & 0x00FF0000) >> 16);
    byte2 = (byte) (byte2 & (~0x00000003));
    tym = (byte) ((tc & 0x30) >> 4);
    byte2 = (byte) (byte2 | tym);

    byte byte1 = (byte) ((i & 0x0000FF00) >> 8);
    byte1 = (byte) (byte1 & (~0x00000003));
    tym = (byte) ((tc & 0x0C) >> 2);
    byte1 = (byte) (byte1 | tym);

    byte byte0 = (byte) ((i & 0x000000FF));
    byte0 = (byte) (byte0 & (~0x00000003));
    tym = (byte) ((tc & 0x03));
    byte0 = (byte) (byte0 | tym);

    byte[] result = (new byte[]{byte3, byte2, byte1, byte0});
    return ByteBuffer.wrap(result).getInt();   
}

问题是,在我使用setRGB将其传递给BuffereImage后,它会更改与我希望的不同的值。我正在用另一个getRGB检查,数值稍有不同,所以我无法读取隐藏的字母。

共有2个答案

龚盛
2023-03-14

我猜一下,假设你的BuffereImage是RGB类型的,即使你认为你已经将它设置为ARGB。RGB类型不支持alpha通道,通过设置像素值,它默认为255。如果您需要正确存储alpha通道中的信息,请以类似于下面的方式加载图像。

用url设置示例案例,但您可以忽略它并加载您想要的任何图像。

您会注意到,如果您将BufferedImage.TYPE_INT_ARGB更改为BufferedImage.TYPE_INT_RGB,当您获取像素值时,alpha通道默认为255。

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.net.URL;

class Blah {
    public static BufferedImage loadImage(String fname) {
        BufferedImage img = null;
        try {
            //File file = new File(fname);
            URL file = new URL("http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo-med.png");
            BufferedImage in = ImageIO.read(file);
            img = new BufferedImage(in.getWidth(), in.getHeight(), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = img.createGraphics();
            g.drawImage(in, 0, 0, null);
            g.dispose();
        } catch (IOException e) { 
            e.printStackTrace();
        }
        return img;
    }

    public static int addLetter(int i, char letter) {
        byte byteChar = (byte)letter;
        int embeddingBits = (((byteChar >> 6) & 3) << 24) +
                            (((byteChar >> 4) & 3) << 16) +
                            (((byteChar >> 2) & 3) << 8) + 
                            (byteChar & 3);
        return (i & 0xfcfcfcfc) + embeddingBits;
    }

    public static char extractLetter(int i) {
        int intChar = (((i >> 24) & 3) << 6) +
                      (((i >> 16) & 3) << 4) +
                      (((i >> 8) & 3) << 2) +
                      (i & 3);
        return (char)intChar;
    }

    public static void main(String[] args) {
        BufferedImage img = loadImage("secret.png");

        int pixel = img.getRGB(0, 0);
        int modifiedPixel = addLetter(pixel, 'b');
        img.setRGB(0, 0, modifiedPixel);

        int checkPixel = img.getRGB(0, 0);
        char newLetter = extractLetter(checkPixel);

        System.out.println(modifiedPixel + " " + checkPixel);
        System.out.println("Extracted letter: " + newLetter);
    }
}
华季萌
2023-03-14

您可能会遇到以下问题:

tym = (byte) ((tc & 0xC0) >> 6);

如果tc(一个字节)是1100 0100,掩码将给出1100 0000,并使用

不确定这是否是你真正的意思。如果你想要的是0000 0011,那么你必须使用

 类似资料:
  • 我想和rapidjson一起工作。 我想生成字符串并将其添加到某个对象中。 我在使用qjson时使用了std::字符串,但在rapidjson的情况下似乎不合适。我不想生成字符串,然后复制它,字符串对象的生存期在对象()生存期之前结束(因此不是一个情况)。json中可能有\0,所以,用空终止字符串也不是一个解决方案。 所以,我必须写我自己的字符串类型?或者使用类似 或者还有其他一些处理字符串的方法

  • null 正如您所看到的,值从图像返回为-实际上,我更改的每个像素都返回为。我做错了什么?只是说不通。提前感谢!

  • 问题内容: java.lang.RuntimeException是“不要为AdapterView调用setOnClickListener。您可能需要setOnItemClickListener,”但这是不正确的。我正在使用setOnItemClickListener根据新选择执行某些操作,但是在用户更改选择之前,我还需要执行一些操作。具体来说,由于每个选择都与不同的数据集相关联,因此我正在收集每个

  • 问题内容: 我正在寻找有关应用引擎如何处理字符编码的一些解释。我正在处理服务器位于应用程序引擎上的客户端服务器应用程序。 这是一个从头开始构建的新应用程序,因此我们到处都使用UTF-8。客户端通过POST(x-www-form- urlencoded)将一些字符串发送到服务器。我收到他们并回声他们。当客户取回它时,它就是ISO-8859-1!POST到blobstore时,当参数以UTF-8,mu

  • 我有一个由多个类实现的接口,这些类也有一些额外的方法。如果我自动连接这个类。有没有办法自动安装这些额外的方法? 例如─ 界面 服务1 服务2 如果我尝试像这样直接自动连接服务- 然后我得到了类似这样的错误-

  • 我解释我这篇文章的目标。 实际上,我想重写如何Android工作的基本上,与应用程序中的字符串。此时此刻,我可以从重写android资源中动态更改它 实际上,我有这个功能,只有当我使用时才能正常工作: 有一种简单的方法,不需要太多代码,就可以覆盖xml中的行为?