我正在编写一个具有简单隐写实现的程序。
我有一个问题,因为如果我对一个像素使用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检查,数值稍有不同,所以我无法读取隐藏的字母。
我猜一下,假设你的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);
}
}
您可能会遇到以下问题:
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中的行为?