How to change it to store message into least significant bit of R,G,B. The code below only embed message into Alpha (0~7bit)
embedInteger deals with embedding the length of the message in the first 32 pixels.
embedByte embeds your message characters, one by one. Every time it is called upon, it takes as an input the next character in your message in byte form, b[i]. There, it embeds one bit per pixel, for a total of 8 bits per byte.
private void embedMessage(BufferedImage img, byte[] mess) {
int messageLength = mess.length;
int imageWidth = img.getWidth(), imageHeight = img.getHeight(),
imageSize = imageWidth * imageHeight;
if(messageLength * 8 + 32 > imageSize) {
System.out.println("Message is too logn");
return;
}
embedInteger(img, messageLength, 0, 0);
for(int i=0; i<mess.length; i++){
embedByte(img, mess[i], i*8+32, 0);
}
}
private void embedInteger(BufferedImage img, int n, int start, int storageBit) {
int maxX = img.getWidth(), maxY = img.getHeight(),
startX = start/maxY, startY = start - startX*maxY, count=0;
for(int i=startX; i<maxX && count<32; i++) {
for(int j=startY; j<maxY && count<32; j++) {
int rgb = img.getRGB(i, j), bit = getBitValue(n, count);
rgb = setBitValue(rgb, storageBit, bit);
img.setRGB(i, j, rgb);
count++;
}
}
}
private void embedByte(BufferedImage img, byte b, int start, int storageBit) {
int maxX = img.getWidth(), maxY = img.getHeight(),
startX = start/maxY, startY = start - startX*maxY, count=0;
for(int i=startX; i<maxX && count<8; i++) {
for(int j=startY; j<maxY && count<8; j++) {
int rgb = img.getRGB(i, j), bit = getBitValue(b, count);
rgb = setBitValue(rgb, storageBit, bit);
img.setRGB(i, j, rgb);
count++;
}
}
}
private int getBitValue(int n, int location) { //n=messageLength, location=count
int v = n & (int) Math.round(Math.pow(2, location));
return v==0?0:1;
}
private int setBitValue(int n, int location, int bit) {
int toggle = (int) Math.pow(2, location), bv = getBitValue(n, location);
if(bv == bit)
return n;
if(bv == 0 && bit == 1){
n |= toggle;
System.out.println("n{toggle: "+n);
}else if(bv == 1 && bit == 0){
n ^= toggle;
}
return n;
}
You want to change the following lines in the
embedMessage
method.The last input, which is 0 in this case, determines the bit location of the RGBA pixel value you will embed your bit. The following image, which is taken from the website you found the code, shows you the bit order for the pixel value.
So, for the LSB of the R component, you want 8, for the G, 16 and for B 24.
Embedding in multiple colour components
A lot of the literature report steganography in RGB. RGBA is very similar, but with the extra information of transparency. Wikipedia is as good a place to read up on that. Effectively, the difference is that RGB has 3 components with 24 bits per pixel in total, while RGBA has 4 components with 32 bits per pixel. By embedding into multiple components, you can increase your hiding capacity by a factor of 3 or 4.
If you want to embed a byte into RGB, you will need 2 and 2/3 pixels (3+3+2 components). But for RGBA you only need two pixels (4+4 components). I will demonstrate how to extend your code to hide a single message in RGBA, as it is simpler in this case. As stated above, this will quadruple your hiding capacity. There are quite a few changes that take place all over the code to make this possible, but they can be boiled down to:
To apply the changes, just start clean with the code as provided in the website and substitute fully the following methods for both the encoding and decoding process.
Encode
Decode
Embedding different secrets in each colour component
I have modified the code so this time you can choose in which colour component you want to hide your secret from the GUI. This is is effectively superior to the version above hiding in all RGBA. Here, you have the versatility in which colour component to hide your message and if you have a really long one, you can split it in four parts. To do this I made the following changes in various part of the code:
storageBit
internally to 0, 8, 16 or 24 depending on whether you have chosen A, R, G or B respectively.To apply the changes, start clean from the code as provided in the website and substitute wholly the following methods, for both the encoding and decoding processes.
Decode