2016-04-04 8 views
0

Ich habe einen Byte-Array aus einem Bild erhalten werden mit dem folgenden Code.Converting Byte-Array in PNG

String path = "/home/mypc/Desktop/Steganography/image.png"; 
File file = new File(path); 
BufferedImage bfimage = ImageIO.read(file); 

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
ImageIO.write(bfimage, "png", baos); 
baos.flush(); 
byte[] img_in_bytes = baos.toByteArray(); 
baos.close(); 

Dann habe ich diese Bytes mit dem folgenden Code wieder in PNG-Bild umgewandelt.

BufferedImage final_img = ImageIO.read(new ByteArrayInputStream(img_in_bytes)); 
File output_file = new File("Stegano2.png"); 
ImageIO.write(final_img, "png", output_file); 

Es ist völlig in Ordnung, wenn ich nur dieses Stück Code ausführen. Aber wenn ich versuche, einige der Bytes zu modifizieren dazwischen, sagen so:

Insert_number_to_image(image_in_bytes, 10); 

und meine Methode „Inset_number_to_image“ geht so:

static void Insert_number_to_image(byte[] image, int size){  
    byte[] size_in_byte = new byte[4]; 
    size_in_byte[0] = (byte)(size >>> 0); 
    size_in_byte[1] = (byte)(size >>> 8); 
    size_in_byte[2] = (byte)(size >>> 16); 
    size_in_byte[3] = (byte)(size >>> 24); 

    byte temp; 
    int count = 0; 

    for(int i=0; i<4; i++) 
    { 
     for(int j=0; j<8; j++) 
     { 
      temp = size_in_byte[i]; 
      temp = (byte)(temp >>> j); 
      temp = (byte)(temp & 1); 
      if(temp == 1) 
      { 
       image[count] = (byte)(image[count] | 1); 
      } 
      else if(temp == 0) 
      { 
       image[count] = (byte)(image[count] & (byte)(~(1))); 
      } 
      count++; 
     } 
    } 
} 

dann danach, wenn ich die modifizierte speichern Byte-Array als PNG-Bild gleichen Code oben erwähnt verwendet wird, ich diese Störung erhalte:

Exception in thread "main" java.lang.IllegalArgumentException: image == null! 
    at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925) 
    at javax.imageio.ImageIO.getWriter(ImageIO.java:1591) 
    at javax.imageio.ImageIO.write(ImageIO.java:1520) 
    at Steganography.main(Steganography.java:211) 

Antwort

3

Was Sie verwenden die rohe Bytestrom eines PNG-Bild ist. PNG is a compressed format, wobei der Bytestream keinen der Pixelwerte direkt widerspiegelt und selbst die Änderung eines Bytes die Datei irreversibel beschädigt.

Was wollen Sie stattdessen ist die Pixeldaten zu einem Byte-Array extrahieren mit

byte[] pixels = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); 

Jetzt können Sie die Pixelwerte ändern, wie Sie wollen. Wenn Sie bereit sind, das zurück in eine Datei zu speichern, convert the pixel byte array to a BufferedImage durch Ihre Pixelanordnung in einem DataBufferByte Objekt setzen und nebenbei, dass zu einem WriteableRaster, die Sie dann ein BufferedImage erstellen verwenden.

Ihre Methode wäre für Formate arbeiten, wo die rohe Bytestrom direkt die Pixel, wie in BMP vertreten ist. Aber selbst dann müssten Sie die ersten paar Bytes überspringen, um den Header nicht zu beschädigen.