2014-04-08 5 views
0

요약하면 알고리즘은 source1, source2, hidden의 세 가지 이미지를 사용합니다. 그런 다음 숨겨진 이미지를 source1 및 source2에 숨 깁니다 (output1 및 output2 생성). output1을 output2에 배치하면 숨겨진 이미지를 볼 수 있습니다. 그러나 output2는 어떻게 든 손상되고 일반 아이디어가 작동하는 동안 숨겨진 이미지 (및 source1)를 볼 수 있습니다. (어렵지만 가능합니다)두 개의 매우 비슷한 이미지를 생성하는 동안 하나의 이미지가 손상됩니다.

http://datagenetics.com/blog/november32013/index.html에서 알고리즘을 구현하려고합니다. ("이 마술은 어떻게 작동합니까?"아래로 스크롤하여 소개를 건너 뜁니다).

편집 : setTwo 메소드가 어떻게 든 동일한 공백을 얻는다는 사실을 알 수 있습니다. blank2를 적용하고 재편성하면 문제가 해결됩니다. 그러나, 나는 여전히 동일한 데이터가 거기에 들어가는 방법을 모른다. 결국, setTwo 알고리즘을 호출하기 전에 항상 두 개의 다른 숫자를 무작위로 추출한다. 누구나 그 이유를 알 수 있을까?

EDIT2 : 인수가 같은지 테스트하기 위해 setTwo를 호출하기 전에 검사를 추가했습니다. 검사는 매번 실패하고 setTwo 내의 검사가 문제를 포착합니다. 나는 데이터가 어떻게 손상되는지 전혀 모른다. "대답을"포기하지 않는

4th image - output 2 - problems

package visualcryptography; 

import java.awt.Color; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.Random; 
import javax.imageio.ImageIO; 
import javax.swing.JLabel; 

/** 
* 
* @author Ugnius 
*/ 
public class VisualCryptography { 

    BufferedImage sourceOne; 
    BufferedImage sourceTwo; 
    BufferedImage hiddenImage; 
    BufferedImage outputOne; 
    BufferedImage outputTwo; 
    GUI loadingBar; 

    static final int black = java.awt.Color.BLACK.getRGB(); 
    static final int white = java.awt.Color.WHITE.getRGB(); 
    static final int whiteToWrite = (new Color(255, 255, 255, 0)).getRGB(); 
    Random r = new Random(); 
    //Color cl; 

    /** 
    * @param args the command line arguments 
    */ 
    public VisualCryptography(BufferedImage source1, BufferedImage source2, BufferedImage hidden, GUI loadingBar) throws Exception { 
     if ((source1.getHeight() != source2.getHeight()) || (source2.getHeight() != hidden.getHeight())) { 
      throw new Exception(); 
     } 
     if ((source1.getWidth() != source2.getWidth()) || (source2.getWidth() != hidden.getWidth())) { 
      throw new Exception(); 
     } 

     sourceOne = source1; 
     sourceTwo = source2; 
     hiddenImage = hidden; 
     this.loadingBar = loadingBar; 
     //cl = java.awt.Color.WHITE; 
     //cl = new Color(cl.getRed(), cl.getGreen(), cl.getBlue(), 0); 
     //white = cl.getRGB(); 
     //System.out.println("this is WHITE:" + cl.getRGB()); 
     //System.out.println("this is my white:" + (new Color(0,0,0).getRGB())); 
     //white = 1; 
     //cl = new Color(255, 255, 255, 255); 
     //white = cl.getRGB(); 

     //white = -1; 
     //white = 16777215; 
     //white = java.awt.Color.WHITE.getRGB(); 
     //byte alpha = (byte) 0xff; 
     //int mc = (alpha << 24) | 0x00ffffff; 
     //white = white & mc; 
     //System.out.println("this is my transparent white:" + white); 
     //System.out.println("this is black" + black); 
    } 

    public void process() throws IOException { 
     int total = sourceOne.getHeight(); 
     outputOne = new BufferedImage(sourceOne.getWidth() * 2, sourceOne.getHeight() * 2, BufferedImage.TYPE_INT_ARGB); 
     outputTwo = new BufferedImage(sourceTwo.getWidth() * 2, sourceTwo.getHeight() * 2, BufferedImage.TYPE_INT_ARGB); 
     for (int height = 0; height < sourceOne.getHeight(); height++) { 
      System.out.println(height + "/" + total); 

      //loadingBar.repaint(); 
      for (int width = 0; width < sourceOne.getWidth(); width++) { 
       //Random r = new Random(); 
       //if ((height > 87) && (width > 190)){ 

       //System.out.println("Hello"); 
       //} 
       if (hiddenImage.getRGB(width, height) != white) { 
        //when the hidden image pixel is BLACK 
        //the combined two cypgher images (OR) have to have all four subpixels set. 
        if ((sourceOne.getRGB(width, height) != white) && (sourceTwo.getRGB(width, height) != white)) { 
         //when bouth source images also have a black pixel, this is easy. Both cypher images need to have three out of 
         //the four subpixels set. The only constraint is that the missing subpixel is not the same on both layers. 
         //one pixel is randomly selected on the first layer, and one is randomly select from the other three on the 
         //second layer 
         int randomized = r.nextInt(4); 
         //randomized = 0; top left 
         //randomized = 1; top right 
         //randomized = 2; bottom left 
         //randomized = 3; bottom right 
         this.setThree(width, height, randomized, outputOne); 
         int newRandomized = r.nextInt(4); 
         while (randomized == newRandomized) { 
          newRandomized = r.nextInt(4); 
         } 
         this.setThree(width, height, newRandomized, outputTwo); 
        } else { 
         if ((sourceOne.getRGB(width, height) != white) && (sourceTwo.getRGB(width, height) == white)) { 
          //When the first image has a black pixel (requiring three subpixels set), and the second image 
          //has a white pixel (requiring two subpixels set), as above, first, a random single subpixel is 
          //selected on the black layer to remove. Next two subpixels are randomly selected on the second 
          //layer with the constraint that one of the selected subpixels is the same as the gap in the 
          //first layer. In this way, when the two are combined, four black subpixels are displayed. 
          int randomized = r.nextInt(4); 
          //randomized = 0; top left 
          //randomized = 1; top right 
          //randomized = 2; bottom left 
          //randomized = 3; bottom right 
          this.setThree(width, height, randomized, outputOne); 
          int random1 = r.nextInt(4); 
          while (random1 == randomized) { 
           random1 = r.nextInt(4); 
          } 
          int random2 = r.nextInt(4); 
          while ((random2 == randomized) || random1 == random2) { 
           random2 = r.nextInt(4); 
          } 
          this.setTwo(width, height, random1, random2, outputTwo); 
         } else { 
          if ((sourceOne.getRGB(width, height) == white) && (sourceTwo.getRGB(width, height) != white)) { 
           //the opposite happens when the first layer is white, and the second layer is black 
           int randomized = r.nextInt(4); 
           //randomized = 0; top left 
           //randomized = 1; top right 
           //randomized = 2; bottom left 
           //randomized = 3; bottom right 
           this.setThree(width, height, randomized, outputTwo); 
           int random1 = r.nextInt(4); 
           while (random1 == randomized) { 
            random1 = r.nextInt(4); 
           } 
           int random2 = r.nextInt(4); 
           while ((random2 == randomized) || random1 == random2) { 
            random2 = r.nextInt(4); 
           } 
           this.setTwo(width, height, random1, random2, outputOne); 
          } else { 
           if ((sourceOne.getRGB(width, height) == white) && (sourceTwo.getRGB(width, height) == white)) { 
            int randomized = r.nextInt(4); 
            int randomized1 = r.nextInt(4); 
            while (randomized == randomized1) { 
             randomized1 = r.nextInt(4); 
            } 
            this.setTwo(width, height, randomized, randomized1, outputOne); 
            int[] remaining = new int[2]; 
            int counter = 0; 
            int number = 0; 
            while (counter != 2) { 
             if ((number != randomized) && (number != randomized1)) { 
              remaining[counter] = number; 
              counter++; 
             } 
             number++; 
            } 
            this.setTwo(width, height, remaining[0], remaining[1], outputTwo); 
           } 
          } 
         } 
        } 
       } else { 
        //when the hidden image pixel is WHITE 
        //the combined two cypher images (OR) have to have any three subpixels set 
        if ((sourceOne.getRGB(width, height) != white) && (sourceTwo.getRGB(width, height) != white)) { 
         //When both source images have a black pixel, this is easy. Both cypher images need to have 
         //three out of the four subpixels set, and these need to be the same subpixels. Three subpixels 
         //are randomly selected and these are set on both of the cypher image layers. 
         int random = r.nextInt(4); 
         this.setThree(width, height, random, outputOne); 
         this.setThree(width, height, random, outputTwo); 
        } else { 
         if ((sourceOne.getRGB(width, height) != white) && (sourceTwo.getRGB(width, height) == white)) { 
          //When the first image has a black pixel (requiring three subpixels set), and the second image 
          //has a white pixel (requiring two subpixels set), as above, first, three random subpixels 
          //are selected on the first layer. Next one of these three subpixels is randomly selected for 
          //removal and this pattern is used on the second layer. 
          int random = r.nextInt(4); 
          this.setThree(width, height, random, outputOne); 
          int random1 = r.nextInt(4); 
          while (random == random1) { 
           random1 = r.nextInt(4); 
          } 
          this.setTwo(width, height, random, random1, outputTwo); 
         } else { 
          if ((sourceOne.getRGB(width, height) == white) && (sourceTwo.getRGB(width, height) != white)) { 
           int random = r.nextInt(4); 
           this.setThree(width, height, random, outputTwo); 
           int random1 = r.nextInt(4); 
           while (random == random1) { 
            random1 = r.nextInt(4); 
           } 
           this.setTwo(width, height, random, random1, outputOne); 
          } else { 
           if ((sourceOne.getRGB(width, height) == white) && (sourceTwo.getRGB(width, height) == white)) { 
            //Finally, if both source pixels are white (requiring two subpixels set), two are selected 
            //at random on the first layer, then one of these is duplicated on the second layer, and a 
            //second random subpixel is selected on the second layer (from the two white subpixels not 
            //selected on the first layer). Both layers have two subpixels, and when combined, there are 
            //three subpixels visbile. 
            int random = r.nextInt(4); 
            //this.setThree(width, height, random, outputTwo); 
            int random1 = r.nextInt(4); 
            while (random == random1) { 
             random1 = r.nextInt(4); 
            } 
            this.setTwo(width, height, random, random1, outputOne); 
            int random2 = r.nextInt(4); 
            if (random2 == random) { 
             random2 = r.nextInt(4); 
            } 
            this.setTwo(width, height, random, random2, outputTwo); 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 

    void setThree(int x, int y, int blank, BufferedImage im) { 
     //blank = 0; top left 
     //blank = 1; top right 
     //blank = 2; bottom left 
     //blank = 3; bottom right 

     im.setRGB(2 * x, 2 * y, black); 
     im.setRGB(2 * x + 1, 2 * y, black); 
     im.setRGB(2 * x, 2 * y + 1, black); 
     im.setRGB(2 * x + 1, 2 * y + 1, black); 
     switch (blank) { 
      case 0: 
       im.setRGB(2 * x, 2 * y, whiteToWrite); 
       break; 
      case 1: 
       im.setRGB(2 * x + 1, 2 * y, whiteToWrite); 
       break; 
      case 2: 
       im.setRGB(2 * x, 2 * y + 1, whiteToWrite); 
       break; 
      case 3: 
       im.setRGB(2 * x + 1, 2 * y + 1, whiteToWrite); 
       break; 
     } 
    } 

    private void setTwo(int x, int y, int blank1, int blank2, BufferedImage im) { 
     //blank = 0; top left 
     //blank = 1; top right 
     //blank = 2; bottom left 
     //blank = 3; bottom right 
     im.setRGB(2 * x, 2 * y, black); 
     im.setRGB(2 * x + 1, 2 * y, black); 
     im.setRGB(2 * x, 2 * y + 1, black); 
     im.setRGB(2 * x + 1, 2 * y + 1, black); 
     switch (blank1) { 
      case 0: 
       im.setRGB(2 * x, 2 * y, whiteToWrite); 
       break; 
      case 1: 
       im.setRGB(2 * x + 1, 2 * y, whiteToWrite); 
       break; 
      case 2: 
       im.setRGB(2 * x, 2 * y + 1, whiteToWrite); 
       break; 
      case 3: 
       im.setRGB(2 * x + 1, 2 * y + 1, whiteToWrite); 
       break; 
     } 
     switch (blank2) { 
      case 0: 
       im.setRGB(2 * x, 2 * y, whiteToWrite); 
       break; 
      case 1: 
       im.setRGB(2 * x + 1, 2 * y, whiteToWrite); 
       break; 
      case 2: 
       im.setRGB(2 * x, 2 * y + 1, whiteToWrite); 
       break; 
      case 3: 
       im.setRGB(2 * x + 1, 2 * y + 1, whiteToWrite); 
       break; 
     } 
    } 

    public BufferedImage[] getOutput() { 
     BufferedImage[] output = new BufferedImage[2]; 
     output[0] = outputOne; 
     output[1] = outputTwo; 
     return output; 
    } 
} 

답변

1

사과

3rd image - output 1 - correct

2nd image - hidden

1st image - source1, source2

. 그러나 나는 거의 사람이 중첩
      } 
         } 
        } 
       } 
      } 
     } 
    } 
} 

... 8 단계와 nextInt의 28 개 항목을 포함 코드 조각을 디버깅 할 용 또는 수 있음을 확신합니다.

당신이하는 일은 무엇이든간에 : 나는 이것이 더 쉽다고 생각합니다. 많이 더 쉽습니다. 밀접하게 2 × 2 픽셀의 패턴을 조사하여 매우 간단한 규칙을 식별 할 수 있습니다 초기 패턴이 픽셀을 산출하기 위해, 수평으로 뒤집 여부 "동전 던지기가"결정

WB 
BW 

입니다

BW 
WB 

두 번째 이미지에서 입력 픽셀이 검정색 인 경우에만 이러한 패턴이 수직으로 뒤집 힙니다.

다음은 구현 예입니다. 도움이 될 것입니다.

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 
import java.awt.image.BufferedImage; 
import java.util.Random; 

import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 


public class VisualCryptographyTest 
{ 
    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       createAndShowGUI(); 
      } 
     }); 
    } 

    private static void createAndShowGUI() 
    { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     f.getContentPane().setLayout(new BorderLayout()); 

     BufferedImage image = createImage("Password"); 

     JLabel originalImageLabel = 
      new JLabel(new ImageIcon(image)); 
     f.getContentPane().add(originalImageLabel, BorderLayout.NORTH); 

     BufferedImage cypherImage0 = createCypherImage(image, true); 
     BufferedImage cypherImage1 = createCypherImage(image, false); 
     VisualCryptographyPanel visualCryptographyPanel = 
      new VisualCryptographyPanel(cypherImage0, cypherImage1); 
     f.getContentPane().add(visualCryptographyPanel, BorderLayout.CENTER); 

     f.setSize(800, 800); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    private static BufferedImage createCypherImage(BufferedImage image, boolean first) 
    { 
     Random random = new Random(0); 
     int w = image.getWidth(); 
     int h = image.getHeight(); 
     BufferedImage cypherImage = new BufferedImage(
      w+w,h+h,BufferedImage.TYPE_INT_ARGB); 

     final int BLACK = Color.BLACK.getRGB(); 
     final int WHITE = 0; 

     for (int y=0; y<h; y++) 
     { 
      for (int x=0; x<w; x++) 
      { 
       int cx = x+x; 
       int cy = y+y; 
       int rgb = image.getRGB(x, y); 

       int p00 = WHITE; 
       int p10 = BLACK; 
       int p01 = BLACK; 
       int p11 = WHITE; 
       int temp = 0; 
       boolean flipH = random.nextBoolean(); 
       if (flipH) 
       { 
        temp=p00; p00=p10; p10=temp; 
        temp=p01; p01=p11; p11=temp; 
       } 
       if (first && rgb == Color.BLACK.getRGB()) 
       { 
        temp=p00; p00=p01; p01=temp; 
        temp=p10; p10=p11; p11=temp; 
       } 
       cypherImage.setRGB(cx+0, cy+0, p00); 
       cypherImage.setRGB(cx+1, cy+0, p10); 
       cypherImage.setRGB(cx+0, cy+1, p01); 
       cypherImage.setRGB(cx+1, cy+1, p11); 

      } 
     } 
     return cypherImage; 
    } 



    private static BufferedImage createImage(String message) 
    { 
     float fontSize = 50.0f; 
     int w = 300; 
     int h = 100; 
     BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 
     Graphics g = image.createGraphics(); 
     g.setColor(Color.WHITE); 
     g.fillRect(0, 0, w, h); 
     g.setColor(Color.BLACK); 
     g.setFont(g.getFont().deriveFont(fontSize)); 
     g.drawString(message, 30, 75); 
     g.dispose(); 
     return image; 

    } 
} 


class VisualCryptographyPanel extends JPanel 
    implements MouseMotionListener, KeyListener 
{ 
    private final BufferedImage cypherImage0; 
    private final BufferedImage cypherImage1; 
    private int imageX = 0; 
    private int imageY = 0; 

    VisualCryptographyPanel(
     BufferedImage cypherImage0, 
     BufferedImage cypherImage1) 
    { 
     setFocusable(true); 
     this.cypherImage0 = cypherImage0; 
     this.cypherImage1 = cypherImage1; 
     addMouseMotionListener(this); 
     addKeyListener(this); 
    } 

    @Override 
    protected void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     g.setColor(Color.WHITE); 
     g.fillRect(0, 0, getWidth(), getHeight()); 

     int x = (getWidth() - cypherImage0.getWidth())/2; 
     int y = (getHeight() - cypherImage0.getHeight())/2; 
     g.drawImage(cypherImage0, x, y, null); 

     g.drawImage(cypherImage1, imageX, imageY, null); 
    } 

    @Override 
    public void mouseMoved(MouseEvent e) 
    { 
     imageX = e.getX(); 
     imageY = e.getY(); 
     repaint(); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) 
    { 
    } 

    @Override 
    public void keyTyped(KeyEvent e) 
    { 
    } 


    @Override 
    public void keyPressed(KeyEvent e) 
    { 
     if (e.getKeyCode() == KeyEvent.VK_UP) 
     { 
      imageY--; 
     } 
     if (e.getKeyCode() == KeyEvent.VK_DOWN) 
     { 
      imageY++; 
     } 
     if (e.getKeyCode() == KeyEvent.VK_LEFT) 
     { 
      imageX--; 
     } 
     if (e.getKeyCode() == KeyEvent.VK_RIGHT) 
     { 
      imageX++; 
     } 
     repaint(); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) 
    { 
    } 


} 
관련 문제