You are on page 1of 6

signup

StackOverflowisaquestionandanswersiteforprofessionalandenthusiastprogrammers.It's100%free,no
registrationrequired.

login

tour

javaStoringmessageintoR,G,BinsteadofAlphaStackOverflow

6/4/2015

help

stackoverflowcareers

Takethe2minutetour

StoringmessageintoR,G,BinsteadofAlpha

HowtochangeittostoremessageintoleastsignificantbitofR,G,B.ThecodebelowonlyembedmessageintoAlpha(0~7bit)
embedIntegerdealswithembeddingthelengthofthemessageinthefirst32pixels.
embedByteembedsyourmessagecharacters,onebyone.Everytimeitiscalledupon,ittakesasaninputthenextcharacterinyour
messageinbyteform,b[i].There,itembedsonebitperpixel,foratotalof8bitsperbyte.
privatevoidembedMessage(BufferedImageimg,byte[]mess){
intmessageLength=mess.length;
intimageWidth=img.getWidth(),imageHeight=img.getHeight(),
imageSize=imageWidth*imageHeight;
if(messageLength*8+32>imageSize){
System.out.println("Messageistoologn");
return;
}
embedInteger(img,messageLength,0,0);
for(inti=0;i<mess.length;i++){
embedByte(img,mess[i],i*8+32,0);
}
}
privatevoidembedInteger(BufferedImageimg,intn,intstart,intstorageBit){
intmaxX=img.getWidth(),maxY=img.getHeight(),
startX=start/maxY,startY=startstartX*maxY,count=0;
for(inti=startX;i<maxX&&count<32;i++){
for(intj=startY;j<maxY&&count<32;j++){
intrgb=img.getRGB(i,j),bit=getBitValue(n,count);
rgb=setBitValue(rgb,storageBit,bit);
img.setRGB(i,j,rgb);
count++;
}
}
}
privatevoidembedByte(BufferedImageimg,byteb,intstart,intstorageBit){
intmaxX=img.getWidth(),maxY=img.getHeight(),
startX=start/maxY,startY=startstartX*maxY,count=0;
for(inti=startX;i<maxX&&count<8;i++){
for(intj=startY;j<maxY&&count<8;j++){
intrgb=img.getRGB(i,j),bit=getBitValue(b,count);
rgb=setBitValue(rgb,storageBit,bit);
img.setRGB(i,j,rgb);
count++;
}
}
}
privateintgetBitValue(intn,intlocation){//n=messageLength,location=count
intv=n&(int)Math.round(Math.pow(2,location));
returnv==0?0:1;
}
privateintsetBitValue(intn,intlocation,intbit){
inttoggle=(int)Math.pow(2,location),bv=getBitValue(n,location);
if(bv==bit)
returnn;
if(bv==0&&bit==1){
n|=toggle;
System.out.println("n{toggle:"+n);
}elseif(bv==1&&bit==0){
n^=toggle;
}
returnn;
}
java image embed decode argb

editedJan24'14at2:11

askedJan23'14at1:33
JarekHuang
59

http://stackoverflow.com/questions/21297633/storingmessageintorgbinsteadofalpha

10

1/6

6/4/2015

javaStoringmessageintoR,G,BinsteadofAlphaStackOverflow

1Answer
Youwanttochangethefollowinglinesinthe embedMessage method.
embedInteger(img,messageLength,0,0);
embedByte(img,mess[i],i*8+32,0);

Thelastinput,whichis0inthiscase,determinesthebitlocationoftheRGBApixelvalueyouwill
embedyourbit.Thefollowingimage,whichistakenfromthewebsiteyoufoundthecode,shows
youthebitorderforthepixelvalue.

So,fortheLSBoftheRcomponent,youwant8,fortheG,16andforB24.

Embeddinginmultiplecolourcomponents
AlotoftheliteraturereportsteganographyinRGB.RGBAisverysimilar,butwiththeextra
informationoftransparency.Wikipediaisasgoodaplacetoreaduponthat.Effectively,the
differenceisthatRGBhas3componentswith24bitsperpixelintotal,whileRGBAhas4
componentswith32bitsperpixel.Byembeddingintomultiplecomponents,youcanincrease
yourhidingcapacitybyafactorof3or4.
IfyouwanttoembedabyteintoRGB,youwillneed2and2/3pixels(3+3+2components).But
forRGBAyouonlyneedtwopixels(4+4components).Iwilldemonstratehowtoextendyour
codetohideasinglemessageinRGBA,asitissimplerinthiscase.Asstatedabove,thiswill
quadrupleyourhidingcapacity.Therearequiteafewchangesthattakeplacealloverthecodeto
makethispossible,buttheycanbeboileddownto:
DitchstorageBitasitisnotnecessaryanymore.
Youcanembedeachbyteintwopixels.Inthefirstpixelyouembedthefirst4bitsintheLSB
oftheA,B,GandRcomponentsofthefirstpixel,andthelast4bitsintheLSBcomponents
ofthe2ndpixel.
Toapplythechanges,juststartcleanwiththecodeasprovidedinthewebsiteandsubstitute
fullythefollowingmethodsforboththeencodinganddecodingprocess.
Encode
privatevoidopenImage(){
java.io.Filef=showFileDialog(true);
try{
sourceImage=ImageIO.read(f);
sourceImage=newBufferedImage(sourceImage.getWidth(),sourceImage.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=sourceImage.createGraphics();
g.drawImage(ImageIO.read(f),0,0,null);
g.dispose();
JLabell=newJLabel(newImageIcon(sourceImage));
originalPane.getViewport().add(l);
this.validate();
}catch(Exceptionex){ex.printStackTrace();}
}
privatevoidembedMessage(BufferedImageimg,Stringmess){
intmessageLength=mess.length();
intimageWidth=img.getWidth(),imageHeight=img.getHeight(),
imageSize=imageWidth*imageHeight;
if(messageLength*2+8>imageSize){
JOptionPane.showMessageDialog(this,"Messageistoolongforthechosenimage",
"Messagetoolong!",JOptionPane.ERROR_MESSAGE);
return;
}
embedInteger(img,messageLength,0);
byteb[]=mess.getBytes();
for(inti=0;i<b.length;i++)
embedByte(img,b[i],i*2+8);
}
privatevoidembedInteger(BufferedImageimg,intn,intstart){
intmaxX=img.getWidth(),maxY=img.getHeight(),
startX=start/maxY,startY=startstartX*maxY,count=0;
for(inti=startX;i<maxX&&count<32;i++){
for(intj=startY;j<maxY&&count<32;j++){
intrgb=img.getRGB(i,j),bit=getBitValue(n,count);
rgb=setBitValue(rgb,0,bit);
bit=getBitValue(n,count+1);rgb=setBitValue(rgb,8,bit);
bit=getBitValue(n,count+2);rgb=setBitValue(rgb,16,bit);
bit=getBitValue(n,count+3);rgb=setBitValue(rgb,24,bit);
img.setRGB(i,j,rgb);

http://stackoverflow.com/questions/21297633/storingmessageintorgbinsteadofalpha

2/6

6/4/2015

javaStoringmessageintoR,G,BinsteadofAlphaStackOverflow

count=count+4;
}
}
}
privatevoidembedByte(BufferedImageimg,byteb,intstart){
intmaxX=img.getWidth(),maxY=img.getHeight(),
startX=start/maxY,startY=startstartX*maxY,count=0;
for(inti=startX;i<maxX&&count<8;i++){
for(intj=startY;j<maxY&&count<8;j++){
if(j==maxY1){
startY=0;
}
intrgb=img.getRGB(i,j),bit=getBitValue(b,count);
rgb=setBitValue(rgb,0,bit);
bit=getBitValue(b,count+1);rgb=setBitValue(rgb,8,bit);
bit=getBitValue(b,count+2);rgb=setBitValue(rgb,16,bit);
bit=getBitValue(b,count+3);rgb=setBitValue(rgb,24,bit);
img.setRGB(i,j,rgb);
count=count+4;
}
}
}

Decode
privatevoidopenImage(){
java.io.Filef=showFileDialog(true);
try{
image=ImageIO.read(f);
image=newBufferedImage(image.getWidth(),image.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=image.createGraphics();
g.drawImage(ImageIO.read(f),0,0,null);
g.dispose();
JLabell=newJLabel(newImageIcon(image));
imagePane.getViewport().add(l);
this.validate();
}catch(Exceptionex){ex.printStackTrace();}
}
privatevoiddecodeMessage(){
intlen=extractInteger(image,0);
byteb[]=newbyte[len];
for(inti=0;i<len;i++)
b[i]=extractByte(image,i*2+8);
message.setText(newString(b));
}
privateintextractInteger(BufferedImageimg,intstart){
intmaxX=img.getWidth(),maxY=img.getHeight(),
startX=start/maxY,startY=startstartX*maxY,count=0;
intlength=0;
for(inti=startX;i<maxX&&count<32;i++){
for(intj=startY;j<maxY&&count<32;j++){
intrgb=img.getRGB(i,j),bit=getBitValue(rgb,0);
length=setBitValue(length,count,bit);
bit=getBitValue(rgb,8);length=setBitValue(length,count+1,bit);
bit=getBitValue(rgb,16);length=setBitValue(length,count+2,bit);
bit=getBitValue(rgb,24);length=setBitValue(length,count+3,bit);
count=count+4;
}
}
returnlength;
}
privatebyteextractByte(BufferedImageimg,intstart){
intmaxX=img.getWidth(),maxY=img.getHeight(),
startX=start/maxY,startY=startstartX*maxY,count=0;
byteb=0;
for(inti=startX;i<maxX&&count<8;i++){
for(intj=startY;j<maxY&&count<8;j++){
if(j==maxY1){
startY=0;
}
intrgb=img.getRGB(i,j),bit=getBitValue(rgb,0);
b=(byte)setBitValue(b,count,bit);
bit=getBitValue(rgb,8);b=(byte)setBitValue(b,count+1,bit);
bit=getBitValue(rgb,16);b=(byte)setBitValue(b,count+2,bit);
bit=getBitValue(rgb,24);b=(byte)setBitValue(b,count+3,bit);
count=count+4;
}
}
returnb;
}

Embeddingdifferentsecretsineachcolourcomponent
Ihavemodifiedthecodesothistimeyoucanchooseinwhichcolourcomponentyouwantto
hideyoursecretfromtheGUI.Thisisiseffectivelysuperiortotheversionabovehidinginall
RGBA.Here,youhavetheversatilityinwhichcolourcomponenttohideyourmessageandifyou
haveareallylongone,youcansplititinfourparts.TodothisImadethefollowingchangesin
variouspartofthecode:
Changethevalueof storageBit internallyto0,8,16or24dependingonwhetheryouhave
chosenA,R,GorBrespectively.

http://stackoverflow.com/questions/21297633/storingmessageintorgbinsteadofalpha

3/6

6/4/2015

javaStoringmessageintoR,G,BinsteadofAlphaStackOverflow

ThischoiceismadeontheGUIsoyoudon'thavetorecompilethecodefordifferentcolour
componentseverytime.
Toapplythechanges,startcleanfromthecodeasprovidedinthewebsiteandsubstitutewholly
thefollowingmethods,forboththeencodinganddecodingprocesses.
publicclassEmbedMessageextendsJFrameimplementsActionListener
{
JButtonopen=newJButton("Open"),embed=newJButton("Embed"),
save=newJButton("Saveintonewfile"),reset=newJButton("Reset");
String[]rgbaList={"B","G","R","A"};
JComboBox<String>chooseRGBA=newJComboBox<>(rgbaList);
JTextAreamessage=newJTextArea(10,3);
BufferedImagesourceImage=null,embeddedImage=null;
JSplitPanesp=newJSplitPane(JSplitPane.HORIZONTAL_SPLIT);
JScrollPaneoriginalPane=newJScrollPane(),
embeddedPane=newJScrollPane();
privatevoidassembleInterface(){
JPanelp=newJPanel(newFlowLayout());
p.add(open);
p.add(chooseRGBA);
p.add(embed);
p.add(save);
p.add(reset);
this.getContentPane().add(p,BorderLayout.SOUTH);
open.addActionListener(this);
embed.addActionListener(this);
save.addActionListener(this);
reset.addActionListener(this);
open.setMnemonic('O');
embed.setMnemonic('E');
save.setMnemonic('S');
reset.setMnemonic('R');
p=newJPanel(newGridLayout(1,1));
p.add(newJScrollPane(message));
message.setFont(newFont("Arial",Font.BOLD,20));
p.setBorder(BorderFactory.createTitledBorder("Messagetobeembedded"));
this.getContentPane().add(p,BorderLayout.NORTH);
sp.setLeftComponent(originalPane);
sp.setRightComponent(embeddedPane);
originalPane.setBorder(BorderFactory.createTitledBorder("OriginalImage"));
embeddedPane.setBorder(BorderFactory.createTitledBorder("SteganographedImage"));
this.getContentPane().add(sp,BorderLayout.CENTER);
}
publicvoidactionPerformed(ActionEventae){
Objecto=ae.getSource();
if(o==open)
openImage();
elseif(o==embed){
intrgbaChoice=chooseRGBA.getSelectedIndex(),sb=0;
if(rgbaChoice==0)
sb=24;
elseif(rgbaChoice==1)
sb=16;
elseif(rgbaChoice==2)
sb=8;
elseif(rgbaChoice==3)
sb=0;
embedMessage(sb);
}
elseif(o==save)
saveImage();
elseif(o==reset)
resetInterface();
}
privatevoidopenImage(){
java.io.Filef=showFileDialog(true);
try{
sourceImage=ImageIO.read(f);
sourceImage=newBufferedImage(sourceImage.getWidth(),sourceImage.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=sourceImage.createGraphics();
g.drawImage(ImageIO.read(f),0,0,null);
g.dispose();
JLabell=newJLabel(newImageIcon(sourceImage));
originalPane.getViewport().add(l);
this.validate();
}catch(Exceptionex){ex.printStackTrace();}
}
privatevoidembedMessage(intstorageBit){
Stringmess=message.getText();
embeddedImage=sourceImage.getSubimage(0,0,
sourceImage.getWidth(),sourceImage.getHeight());
embedMessage(embeddedImage,mess,storageBit);
JLabell=newJLabel(newImageIcon(embeddedImage));
embeddedPane.getViewport().add(l);
this.validate();
}
privatevoidembedMessage(BufferedImageimg,Stringmess,intstorageBit){
intmessageLength=mess.length();

http://stackoverflow.com/questions/21297633/storingmessageintorgbinsteadofalpha

4/6

6/4/2015

javaStoringmessageintoR,G,BinsteadofAlphaStackOverflow

intimageWidth=img.getWidth(),imageHeight=img.getHeight(),
imageSize=imageWidth*imageHeight;
if(messageLength*8+32>imageSize){
JOptionPane.showMessageDialog(this,"Messageistoolongforthechosenimage",
"Messagetoolong!",JOptionPane.ERROR_MESSAGE);
return;
}
embedInteger(img,messageLength,0,storageBit);
byteb[]=mess.getBytes();
for(inti=0;i<b.length;i++)
embedByte(img,b[i],i*8+32,storageBit);
}

Decode
publicclassDecodeMessageextendsJFrameimplementsActionListener
{
JButtonopen=newJButton("Open"),decode=newJButton("Decode"),
reset=newJButton("Reset");
String[]rgbaList={"B","G","R","A"};
JComboBox<String>chooseRGBA=newJComboBox<>(rgbaList);
JTextAreamessage=newJTextArea(10,3);
BufferedImageimage=null;
JScrollPaneimagePane=newJScrollPane();
privatevoidassembleInterface(){
JPanelp=newJPanel(newFlowLayout());
p.add(open);
p.add(chooseRGBA);
p.add(decode);
p.add(reset);
this.getContentPane().add(p,BorderLayout.NORTH);
open.addActionListener(this);
decode.addActionListener(this);
reset.addActionListener(this);
open.setMnemonic('O');
decode.setMnemonic('D');
reset.setMnemonic('R');
p=newJPanel(newGridLayout(1,1));
p.add(newJScrollPane(message));
message.setFont(newFont("Arial",Font.BOLD,20));
p.setBorder(BorderFactory.createTitledBorder("Decodedmessage"));
message.setEditable(false);
this.getContentPane().add(p,BorderLayout.SOUTH);
imagePane.setBorder(BorderFactory.createTitledBorder("SteganographedImage"));
this.getContentPane().add(imagePane,BorderLayout.CENTER);
}
publicvoidactionPerformed(ActionEventae){
Objecto=ae.getSource();
if(o==open)
openImage();
elseif(o==decode){
intrgbaChoice=chooseRGBA.getSelectedIndex(),sb=0;
if(rgbaChoice==0)
sb=24;
elseif(rgbaChoice==1)
sb=16;
elseif(rgbaChoice==2)
sb=8;
elseif(rgbaChoice==3)
sb=0;
decodeMessage(sb);
}
elseif(o==reset)
resetInterface();
}
privatevoidopenImage(){
java.io.Filef=showFileDialog(true);
try{
image=ImageIO.read(f);
image=newBufferedImage(image.getWidth(),image.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=image.createGraphics();
g.drawImage(ImageIO.read(f),0,0,null);
g.dispose();
JLabell=newJLabel(newImageIcon(image));
imagePane.getViewport().add(l);
this.validate();
}catch(Exceptionex){ex.printStackTrace();}
}
privatevoiddecodeMessage(intstorageBit){
intlen=extractInteger(image,0,storageBit);
byteb[]=newbyte[len];
for(inti=0;i<len;i++)
b[i]=extractByte(image,i*8+32,storageBit);
message.setText(newString(b));
}
privatebyteextractByte(BufferedImageimg,intstart,intstorageBit){
intmaxX=img.getWidth(),maxY=img.getHeight(),
startX=start/maxY,startY=startstartX*maxY,count=0;
byteb=0;
for(inti=startX;i<maxX&&count<8;i++){

http://stackoverflow.com/questions/21297633/storingmessageintorgbinsteadofalpha

5/6

6/4/2015

javaStoringmessageintoR,G,BinsteadofAlphaStackOverflow

for(intj=startY;j<maxY&&count<8;j++){
if(j==maxY1){
startY=0;
}
intrgb=img.getRGB(i,j),bit=getBitValue(rgb,storageBit);
b=(byte)setBitValue(b,count,bit);
count++;
}
}
returnb;
}

editedJan25'14at2:57

answeredJan24'14at16:26
Reti43
751

10

19

Ireadsomearticle,theysaidtheyembededmessagetoLSBofR,GandB,butifitisenoughforonlyone
componenttoembedthemessage,whyneedtoembedthemessageintoR,G,B,threeofcomponent??
ButifiwanttoembedthreemessagesintothreeofR,G,Bcomponent,howcaniexactlydothatinthe
code,becauseitisonlyonlocationbecontrolledby storeageBit . JarekHuang Jan24'14at16:42
1 Ihaveupdatedtotheanswertoexplainwhyhidinginmultiplecomponentsissometimespreferable.Ihave
alsoprovidedworkingcodeforhowtohideamessageinallfourcomponentsandhowtohidedifferent
messagesineach.Reti43Jan25'14at3:02
1 Youneedfoursteps.Firststep,takethevalueofthepixeltoembedto.Second,getvalueofbityouwant
toembed.Third,embedthatbitintothepixelvalue,whichisjustanintegervalueattachedinthe rgb
object.Forth,updatethepixelwiththenewvalueof rgb .Theotherquestionaboutthe
set/getBitValues wasexplainedtoyouinanotherquestion. Reti43 Jan25'14at16:48
1 Youembedfourbitsperpixel,soyouneedtopixelstofitawholebyteandyouneed8pixelstofitthe
32bitmessagelengthinfo.Reti43Jan25'14at17:36
1 letuscontinuethisdiscussioninchatReti43Jan25'14at20:18

http://stackoverflow.com/questions/21297633/storingmessageintorgbinsteadofalpha

6/6

You might also like