我可以将图像隐藏在另一个内部并显示原始图像,但现在需要为进程添加密码
public BufferedImage encodeImage(String key, BufferedImage cover, BufferedImage secret) {
int height = secret.getHeight();
int width = secret.getWidth();
byte[] bytes = getImageBytes(secret);
bytes = encrypt(bytes, key.getBytes());
// get byte array for width, height, and message (8 bytes = 1 bit)
byte[] widthArray = getBytesFromInt(WIDTH_BITS/8, width);
byte[] heightArray = getBytesFromInt(HEIGHT_BITS/8, height);
byte[] messageLengthArray = getBytesFromInt(MESSAGE_LENGTH_BITS/8, bytes.length);
byte[] imageArray = getImageBytes(cover);
// hide bytes with offset of previous bit lengths added up
hideBytes(imageArray, messageLengthArray, 0);
hideBytes(imageArray, widthArray, MESSAGE_LENGTH_BITS);
hideBytes(imageArray, heightArray, MESSAGE_LENGTH_BITS + WIDTH_BITS);
hideBytes(imageArray, bytes, MESSAGE_LENGTH_BITS + WIDTH_BITS + HEIGHT_BITS);
return cover;
}
但我无法使用相同的流程来检索秘密图片
更新: 但是我不能使用相同的过程来检索秘密图像
public BufferedImage decodeImage(String key, BufferedImage bimg) {
byte[] imageArray = getImageBytes(bimg);
int length = 0, height = 0, width = 0;
// loop through all encoded length bits and store value in corresponding variable
for (int i = 0; i < (MESSAGE_LENGTH_BITS + WIDTH_BITS + HEIGHT_BITS); i++) {
if (i < MESSAGE_LENGTH_BITS)
length = (length << 1) | (imageArray[i] & 1);
else if (i < MESSAGE_LENGTH_BITS + WIDTH_BITS)
width = (width << 1) | (imageArray[i] & 1);
else
height = (height << 1) | (imageArray[i] & 1);
}
byte[] result = new byte[length];
// skip all encoded lengths (message_length, width and height bits)
int index = MESSAGE_LENGTH_BITS + WIDTH_BITS + HEIGHT_BITS;
// loop til length of message and grab each LSB from image
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < 8; j++) { // each bit
// shift by 1 and grab last bit of next image byte
result[i] = (byte) ((result[i] << 1) | (imageArray[index] & 1));
index++;
}
}
// swap blue with red to follow RGB sequence from BGR
for (int i = 0; i < result.length; i+=3) {
byte temp = result[i];
result[i] = result[i+2];
result[i+2] = temp;
}
// create image
BufferedImage b = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
WritableRaster raster = b.getRaster();
raster.setDataElements(0, 0, width, height, result);
return b;
}
密码处理仅对具有秘密图像的数据进行异或
public static byte[] encrypt(byte[] key, byte[] plainText) {
byte[] result = new byte[plainText.length];
for (int i = 0; i < plainText.length; i++) {
result[i] = (byte) (plainText[i] ^ key[i]);
}
return result;
}
该过程中的其他方法 隐藏方法和int到字节并从图像
获取字节private void hideBytes(byte[] bimg, byte[] bytes, int offset) {
for (int i = 0; i < bytes.length; i++) {
int character = bytes[i];
for (int j = 7; j >= 0; j--) { // 8 bits per character
// get corresponding bit
int bit = (character >> j) & 1;
// get last image byte, set last bit to 0 ( AND 0xFE) then OR with bit
bimg[offset] = (byte) ((bimg[offset] & 0xFE) | bit);
offset++;
}
}
}
private byte[] getBytesFromInt(int size, int number) {
byte[] b = new byte[size];
for (int i = size-1, shift = 0; i >= 0; i--, shift += 8)
b[i] = (byte) ((number & (0x000000FF << shift)) >> shift);
return b;
}
private byte[] getImageBytes(BufferedImage bimg) {
WritableRaster raster = bimg.getRaster();
DataBufferByte dbb = (DataBufferByte) raster.getDataBuffer();
return dbb.getData();
}