2014-12-20 3 views
1

간단한 스테 가노 그래피 구현으로 프로그램을 작성합니다.스테 가노 그라피와 함께 getRGB와 setRGB를 사용할 방법이 있습니까?

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); 

결과는

내가 어떤 도움과 이해에 대한 greatefull 될 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(); 

입니다 ... 그래서 stegenography이 작동하지 않습니다 다릅니다. 자바

에서 메신저 아직도 beginer에 편집 :

나는 내 문제를 한 번 더 설명하려고합니다 : 기능 를 사용 임 // 내가 int로 - 픽셀 // 문자 문자에 대한 getRGB를의 메신저 통과 결과를 - 즉, A, R, G 및 B 값의 2 LSB를 더하는 문자 public static int addLetter (int i, char letter) { 바이트 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

그냥 제안 사항입니다. 영어 이름을 (모든) 변수에 부여하면 다른 사람들이 문제를 더 잘 이해할 수 있습니다. – Bono

+0

'obraz'의 데이터 유형은 무엇입니까? – karlphillip

+0

obraz is BufferedImage 죄송합니다, obraz는 이미지입니다. zastap2ostatnie는 change2last입니다. – wiwo

답변

0

여기에 문제가있을 수 있습니다 :

tym = (byte) ((tc & 0xC0) >> 6); 

tc하는 경우이다 (이는 byte) 1100 0100이며, (6)에 의해 1100 0000과 오른쪽 이동은 >> 운영자가 ... 1111 1111을 줄 것이다 사용하여 줄 것이다 마스크!

이것이 실제적인 의미인지는 확실하지 않습니다. 원하는 항목이 0000 0011 인 경우 >>>을 사용해야합니다. >> 연산자는 부호 비트를 전달합니다.

+0

여기에서 문제가되어서는 안됩니다. 그가 이상한 심볼을 사용하지 않는 한, 'b'의 경우와 마찬가지로 ascii 값은 127보다 작고 부호 비트는 0이어야합니다. 실제 문제는 올바른 데이터를 포함하는 것이 아니라 수정 된 데이터를 설정하는 것입니다. 가치가 무엇이든간에 이미지로 돌아가고 나중에 검색 할 수는 없습니다. – Reti43

0

BufferedImage가 ARGB로 설정했다고 생각한다고해도, BufferedImage는 RGB 유형이라고 가정합니다. RGB 유형은 알파 채널을 지원하지 않으며 픽셀 값을 설정하여 기본값은 255입니다. 알파 채널의 정보를 제대로 저장해야하는 경우 아래와 비슷한 방식으로 이미지를로드해야합니다.

예를 들어 URL을 설정했지만 무시하고 원하는 이미지를로드 할 수 있습니다.

BufferedImage.TYPE_INT_ARGBBufferedImage.TYPE_INT_RGB으로 변경하면 픽셀 값을 가져올 때 알파 채널이 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); 
    } 
} 
관련 문제