Java 将消息存储到R、G、B而不是Alpha中

Java 将消息存储到R、G、B而不是Alpha中,java,image,embed,decode,argb,Java,Image,Embed,Decode,Argb,如何将其更改为将消息存储到R、G、B的最低有效位。 下面的代码仅将消息嵌入Alpha(0~7bit) EmbeddeInteger处理在前32个像素中嵌入消息的长度 EmbeddeByte一个接一个地嵌入消息字符。每次调用它时,它都以字节形式将消息中的下一个字符b[i]作为输入。在那里,它每像素嵌入一位,每字节总共嵌入8位 private void embedMessage(BufferedImage img, byte[] mess) { int messageLength = mes

如何将其更改为将消息存储到R、G、B的最低有效位。 下面的代码仅将消息嵌入Alpha(0~7bit)

EmbeddeInteger处理在前32个像素中嵌入消息的长度

EmbeddeByte一个接一个地嵌入消息字符。每次调用它时,它都以字节形式将消息中的下一个字符b[i]作为输入。在那里,它每像素嵌入一位,每字节总共嵌入8位

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;

}
private void嵌入消息(buffereImage img,字节[]mess){
int messageLength=mess.length;
int imageWidth=img.getWidth(),imageHeight=img.getHeight(),
图像大小=图像宽度*图像高度;
如果(messageLength*8+32>imageSize){
System.out.println(“消息太logn”);
返回;
}
嵌入整数(img,messageLength,0,0);

对于(int i=0;i您希望更改
embedMessage
方法中的以下行

embedInteger(img, messageLength, 0, 0);
embedByte(img, mess[i], i*8+32, 0);
最后一个输入(在本例中为0)确定要嵌入位的RGBA像素值的位位置。下图取自找到代码的网站,显示像素值的位顺序

所以,对于R分量的LSB,你需要8,对于G,16和B24

嵌入多种颜色成分 很多文献报道RGB中的隐写术。RGBA非常相似,但有额外的透明度信息。这是一个阅读的好地方。实际上,区别在于RGB有3个组件,每个像素24位,而RGBA有4个组件,每个像素32位。通过嵌入多个组件,你可以你可以将你的隐藏能力提高3到4倍

如果你想在RGB中嵌入一个字节,你需要2和2/3像素(3+3+2分量)。但是对于RGBA,你只需要两个像素(4+4分量)。我将演示如何扩展代码以在RGBA中隐藏单个消息,因为在本例中更简单。如上所述,这将使您的隐藏容量翻两番。为了实现这一点,代码中进行了很多更改,但可以归结为:

  • 因为不再需要了,所以将其丢弃
  • 您可以将每个字节嵌入两个像素。在第一个像素中,您将前4位嵌入第一个像素的A、B、G和R分量的LSB,最后4位嵌入第二个像素的LSB分量
要应用更改,只需按照网站中提供的代码开始清理,并用以下方法完全替代编码和解码过程

编码

private void openImage() {
   java.io.File f = showFileDialog(true);
   try {   
      sourceImage = ImageIO.read(f);
      sourceImage = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = sourceImage.createGraphics();
      g.drawImage(ImageIO.read(f), 0, 0, null);
      g.dispose();
      JLabel l = new JLabel(new ImageIcon(sourceImage));
      originalPane.getViewport().add(l);
      this.validate();
      } catch(Exception ex) { ex.printStackTrace(); }
   }

private void embedMessage(BufferedImage img, String mess) {
   int messageLength = mess.length();

   int imageWidth = img.getWidth(), imageHeight = img.getHeight(),
      imageSize = imageWidth * imageHeight;
   if(messageLength * 2 + 8 > imageSize) {
      JOptionPane.showMessageDialog(this, "Message is too long for the chosen image",
         "Message too long!", JOptionPane.ERROR_MESSAGE);
      return;
      }
   embedInteger(img, messageLength, 0);

   byte b[] = mess.getBytes();
   for(int i=0; i<b.length; i++)
      embedByte(img, b[i], i*2+8);
   }

private void embedInteger(BufferedImage img, int n, int start) {
   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, 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); 
         count = count+4;
         }
      }
   }

private void embedByte(BufferedImage img, byte b, int start) {
   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++) {
         if(j==maxY-1){
            startY = 0;
            }
         int rgb = 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;
         }
      }
   }
private void openImage() {
   java.io.File f = showFileDialog(true);
   try {   
      image = ImageIO.read(f);
      image = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = image.createGraphics();
      g.drawImage(ImageIO.read(f), 0, 0, null);
      g.dispose();
      JLabel l = new JLabel(new ImageIcon(image));
      imagePane.getViewport().add(l);
      this.validate();
      } catch(Exception ex) { ex.printStackTrace(); }
   }

private void decodeMessage() {
   int len = extractInteger(image, 0);
   byte b[] = new byte[len];
   for(int i=0; i<len; i++)
      b[i] = extractByte(image, i*2+8);
   message.setText(new String(b));
   }

private int extractInteger(BufferedImage img, int start) {
   int maxX = img.getWidth(), maxY = img.getHeight(), 
      startX = start/maxY, startY = start - startX*maxY, count=0;
   int length = 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(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;
         }
      }
   return length;
   }

private byte extractByte(BufferedImage img, int start) {
   int maxX = img.getWidth(), maxY = img.getHeight(), 
      startX = start/maxY, startY = start - startX*maxY, count=0;
   byte b = 0;
   for(int i=startX; i<maxX && count<8; i++) {
      for(int j=startY; j<maxY && count<8; j++) {
         if(j==maxY-1){
            startY = 0;
            }
         int rgb = 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;
         }
      }
   return b;
   }
public class DecodeMessage extends JFrame implements ActionListener
{
JButton open = new JButton("Open"), decode = new JButton("Decode"),
   reset = new JButton("Reset");
String[] rgbaList = { "B", "G", "R", "A" };
JComboBox<String> chooseRGBA = new JComboBox<>(rgbaList);
JTextArea message = new JTextArea(10,3);
BufferedImage image = null;
JScrollPane imagePane = new JScrollPane();

private void assembleInterface() {
   JPanel p = new JPanel(new FlowLayout());
   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 = new JPanel(new GridLayout(1,1));
   p.add(new JScrollPane(message));
   message.setFont(new Font("Arial",Font.BOLD,20));
   p.setBorder(BorderFactory.createTitledBorder("Decoded message"));
   message.setEditable(false);
   this.getContentPane().add(p, BorderLayout.SOUTH);

   imagePane.setBorder(BorderFactory.createTitledBorder("Steganographed Image"));
   this.getContentPane().add(imagePane, BorderLayout.CENTER);
   }

public void actionPerformed(ActionEvent ae) {
   Object o = ae.getSource();
   if(o == open)
      openImage();
   else if(o == decode){
      int rgbaChoice = chooseRGBA.getSelectedIndex(), sb = 0;
      if(rgbaChoice == 0)
         sb = 24;
      else if(rgbaChoice == 1)
         sb = 16;
      else if(rgbaChoice == 2)
         sb = 8;
      else if(rgbaChoice == 3)
         sb = 0;
      decodeMessage(sb);
      }
   else if(o == reset) 
      resetInterface();
   }

private void openImage() {
   java.io.File f = showFileDialog(true);
   try {   
      image = ImageIO.read(f);
      image = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = image.createGraphics();
      g.drawImage(ImageIO.read(f), 0, 0, null);
      g.dispose();
      JLabel l = new JLabel(new ImageIcon(image));
      imagePane.getViewport().add(l);
      this.validate();
      } catch(Exception ex) { ex.printStackTrace(); }
   }

private void decodeMessage(int storageBit) {
   int len = extractInteger(image, 0, storageBit);
   byte b[] = new byte[len];
   for(int i=0; i<len; i++)
      b[i] = extractByte(image, i*8+32, storageBit);
   message.setText(new String(b));
   }

private byte extractByte(BufferedImage img, int start, int storageBit) {
   int maxX = img.getWidth(), maxY = img.getHeight(), 
      startX = start/maxY, startY = start - startX*maxY, count=0;
   byte b = 0;
   for(int i=startX; i<maxX && count<8; i++) {
      for(int j=startY; j<maxY && count<8; j++) {
         if(j==maxY-1){
            startY = 0;
            }
         int rgb = img.getRGB(i, j), bit = getBitValue(rgb, storageBit);
         b = (byte)setBitValue(b, count, bit);
         count++;
         }
      }
   return b;
   }
解码

private void openImage() {
   java.io.File f = showFileDialog(true);
   try {   
      sourceImage = ImageIO.read(f);
      sourceImage = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = sourceImage.createGraphics();
      g.drawImage(ImageIO.read(f), 0, 0, null);
      g.dispose();
      JLabel l = new JLabel(new ImageIcon(sourceImage));
      originalPane.getViewport().add(l);
      this.validate();
      } catch(Exception ex) { ex.printStackTrace(); }
   }

private void embedMessage(BufferedImage img, String mess) {
   int messageLength = mess.length();

   int imageWidth = img.getWidth(), imageHeight = img.getHeight(),
      imageSize = imageWidth * imageHeight;
   if(messageLength * 2 + 8 > imageSize) {
      JOptionPane.showMessageDialog(this, "Message is too long for the chosen image",
         "Message too long!", JOptionPane.ERROR_MESSAGE);
      return;
      }
   embedInteger(img, messageLength, 0);

   byte b[] = mess.getBytes();
   for(int i=0; i<b.length; i++)
      embedByte(img, b[i], i*2+8);
   }

private void embedInteger(BufferedImage img, int n, int start) {
   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, 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); 
         count = count+4;
         }
      }
   }

private void embedByte(BufferedImage img, byte b, int start) {
   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++) {
         if(j==maxY-1){
            startY = 0;
            }
         int rgb = 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;
         }
      }
   }
private void openImage() {
   java.io.File f = showFileDialog(true);
   try {   
      image = ImageIO.read(f);
      image = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = image.createGraphics();
      g.drawImage(ImageIO.read(f), 0, 0, null);
      g.dispose();
      JLabel l = new JLabel(new ImageIcon(image));
      imagePane.getViewport().add(l);
      this.validate();
      } catch(Exception ex) { ex.printStackTrace(); }
   }

private void decodeMessage() {
   int len = extractInteger(image, 0);
   byte b[] = new byte[len];
   for(int i=0; i<len; i++)
      b[i] = extractByte(image, i*2+8);
   message.setText(new String(b));
   }

private int extractInteger(BufferedImage img, int start) {
   int maxX = img.getWidth(), maxY = img.getHeight(), 
      startX = start/maxY, startY = start - startX*maxY, count=0;
   int length = 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(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;
         }
      }
   return length;
   }

private byte extractByte(BufferedImage img, int start) {
   int maxX = img.getWidth(), maxY = img.getHeight(), 
      startX = start/maxY, startY = start - startX*maxY, count=0;
   byte b = 0;
   for(int i=startX; i<maxX && count<8; i++) {
      for(int j=startY; j<maxY && count<8; j++) {
         if(j==maxY-1){
            startY = 0;
            }
         int rgb = 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;
         }
      }
   return b;
   }
public class DecodeMessage extends JFrame implements ActionListener
{
JButton open = new JButton("Open"), decode = new JButton("Decode"),
   reset = new JButton("Reset");
String[] rgbaList = { "B", "G", "R", "A" };
JComboBox<String> chooseRGBA = new JComboBox<>(rgbaList);
JTextArea message = new JTextArea(10,3);
BufferedImage image = null;
JScrollPane imagePane = new JScrollPane();

private void assembleInterface() {
   JPanel p = new JPanel(new FlowLayout());
   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 = new JPanel(new GridLayout(1,1));
   p.add(new JScrollPane(message));
   message.setFont(new Font("Arial",Font.BOLD,20));
   p.setBorder(BorderFactory.createTitledBorder("Decoded message"));
   message.setEditable(false);
   this.getContentPane().add(p, BorderLayout.SOUTH);

   imagePane.setBorder(BorderFactory.createTitledBorder("Steganographed Image"));
   this.getContentPane().add(imagePane, BorderLayout.CENTER);
   }

public void actionPerformed(ActionEvent ae) {
   Object o = ae.getSource();
   if(o == open)
      openImage();
   else if(o == decode){
      int rgbaChoice = chooseRGBA.getSelectedIndex(), sb = 0;
      if(rgbaChoice == 0)
         sb = 24;
      else if(rgbaChoice == 1)
         sb = 16;
      else if(rgbaChoice == 2)
         sb = 8;
      else if(rgbaChoice == 3)
         sb = 0;
      decodeMessage(sb);
      }
   else if(o == reset) 
      resetInterface();
   }

private void openImage() {
   java.io.File f = showFileDialog(true);
   try {   
      image = ImageIO.read(f);
      image = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = image.createGraphics();
      g.drawImage(ImageIO.read(f), 0, 0, null);
      g.dispose();
      JLabel l = new JLabel(new ImageIcon(image));
      imagePane.getViewport().add(l);
      this.validate();
      } catch(Exception ex) { ex.printStackTrace(); }
   }

private void decodeMessage(int storageBit) {
   int len = extractInteger(image, 0, storageBit);
   byte b[] = new byte[len];
   for(int i=0; i<len; i++)
      b[i] = extractByte(image, i*8+32, storageBit);
   message.setText(new String(b));
   }

private byte extractByte(BufferedImage img, int start, int storageBit) {
   int maxX = img.getWidth(), maxY = img.getHeight(), 
      startX = start/maxY, startY = start - startX*maxY, count=0;
   byte b = 0;
   for(int i=startX; i<maxX && count<8; i++) {
      for(int j=startY; j<maxY && count<8; j++) {
         if(j==maxY-1){
            startY = 0;
            }
         int rgb = img.getRGB(i, j), bit = getBitValue(rgb, storageBit);
         b = (byte)setBitValue(b, count, bit);
         count++;
         }
      }
   return b;
   }
公共类DecodeMessage扩展JFrame实现ActionListener
{
JButton打开=新JButton(“打开”),解码=新JButton(“解码”),
重置=新的按钮(“重置”);
字符串[]rgbaList={“B”、“G”、“R”、“A”};
JComboBox chooseRGBA=新的JComboBox(rgbaList);
JTextArea消息=新的JTextArea(10,3);
BuffereImage图像=空;
JScrollPane imagePane=新的JScrollPane();
私有void集合接口(){
JPanel p=newjpanel(newflowlayout());
p、 添加(打开);
p、 添加(选择GBA);
p、 添加(解码);
p、 添加(重置);
this.getContentPane().add(p,BorderLayout.NORTH);
open.addActionListener(this);
decode.addActionListener(这个);
reset.addActionListener(这个);
open.set助记符('O');
decode.setmemonic('D');
reset.set助记符('R');
p=新JPanel(新网格布局(1,1));
p、 添加(新的JScrollPane(消息));
message.setFont(新字体(“Arial”,字体粗体,20));
p、 setBordOrder(BorderFactory.createTitledBorder(“解码消息”);
message.setEditable(false);
this.getContentPane().add(p,BorderLayout.SOUTH);
setboorder(BorderFactory.createTitleBorder(“隐写图像”);
this.getContentPane().add(imagePane,BorderLayout.CENTER);
}
已执行的公共无效行动(行动事件ae){
对象o=ae.getSource();
如果(o==打开)
openImage();
else if(o==解码){
int rgbaChoice=chooseRGBA.getSelectedIndex(),sb=0;
如果(rgbaChoice==0)
sb=24;
else if(rgbaChoice==1)
sb=16;
else if(rgbaChoice==2)
sb=8;
else if(rgbaChoice==3)
sb=0;
(某人);
}
否则如果(o==重置)
重置接口();
}
私有void openImage(){
java.io.File f=showFileDialog(true);
试试{
图像=图像读取(f);
image=new BufferedImage(image.getWidth()、image.getHeight()、BufferedImage.TYPE\u INT\u ARGB);
Graphics2D g=image.createGraphics();
g、 drawImage(ImageIO.read(f),0,0,null);
g、 处置();
JLabel l=新JLabel(新图像图标(图像));
imagePane.getViewport().add(l);
这个。validate();
}catch(异常ex){ex.printStackTrace();}
}
私有无效解码消息(int-storageBit){
int len=extractInteger(图像,0,存储位);
字节b[]=新字节[len];

对于(int i=0;我读了一些文章,他们说他们将消息嵌入到了R,G和B的LSB中,但如果只有一个组件嵌入消息就足够了,为什么需要将消息嵌入到R,G,B,三个组件中??但是如果我想将三条消息嵌入到R,G,B三个组件中,我如何在代码中准确地做到这一点,因为它只在位置上。)n由
storeageBit
控制。我已经更新了答案,解释了为什么有时最好隐藏在多个组件中。我还提供了如何在所有四个组件中隐藏消息以及如何在每个组件中隐藏不同消息的工作代码。您需要四个步骤。第一步,获取要嵌入的像素值。第二步,获取要嵌入的位的值。第三,将该位嵌入到像素值中,该值只是附加在
rgb
对象中的整数值。第四,使用
rgb
的新值更新像素。关于
设置/getBitValues