我正在编写一个简单的隐写术实现程序。
我有一个问题因为如果我使用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);
并且结果不同,所以stegenography不起作用......
这是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();
对于任何帮助和理解,我都会非常感激。我仍然是Java的初学者
编辑:
我会再试一次解释我的问题: 我正在使用功能 // int i - 我为像素传递getRGB的结果 // char letter - 这是一个加上A,R,G和B值的2 LSB的字母 public static int addLetter(int i,char letter) { byte tym,tc; tc =(字节)字母; 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将其传递给BufferedImage之后,它会更改与我想要的值不同的值。我通过另一个getRGB检查它,并且值略有不同,所以我无法读取我的隐藏信件。
答案 0 :(得分:0)
您可能在此处遇到问题:
tym = (byte) ((tc & 0xC0) >> 6);
如果tc
(byte
}为1100 0100
,则掩码将为1100 0000
,并使用>>
运算符右移6 ...... 1111 1111
!
不确定这是不是你的意思。如果你想要的是0000 0011
,那么你必须使用>>>
。 >>
运算符带有符号位。
答案 1 :(得分:0)
我会猜测并假设您的BufferedImage是RGB类型,即使您认为您已将其设置为ARGB。 RGB类型不支持Alpha通道,并且通过设置像素值,默认为255.如果您需要正确存储Alpha通道中的信息,则以类似于下面的方式加载图像应该有效。
使用网址设置的示例案例,但您可以忽略它并加载您想要的任何图像。
您会注意到,如果您将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);
}
}