2017-01-09 14 views
5

Mam obraz, który jest przechowywany jako tablica bajtów [], i chcę odwrócić obraz w pionie przed zapisaniem bajtów na dysk gdzie indziej.Odwróć obraz przechowywany jako tablica bajtowa

Bajty obrazu pochodzą ze skompresowanego pliku obrazu jp2. Sprawdziłem implementację czegoś takiego jak Flip image stored as a byte[] array, ale nie pracuję na Androidzie i nie mam dostępu do BitmapFactory. Przyjrzałem się także przekształceniu tablicy bajtów w obraz BufferedImage, a następnie w odwróceniu, ale wysokość i szerokość obrazu nie jest znana w bieżącym kontekście (EDIT: Zmodyfikowałem kod tak, aby wysokość i szerokość były teraz znany).

Czy jest jakiś sposób na zrobienie tego tylko przy ścisłej manipulacji tablicą?

EDIT: Próba kod klapki

public static byte[] flip(byte[] imageBytes) { 
    //separate out the sub arrays 
    byte[] holder = new byte[imageBytes.length]; 
    byte[] subArray = new byte[dimWidth];//dimWidth is the image width, or number of matrix columns 
    int subCount = 0; 
    for (int i = 0; i < imageBytes.length; i++) { 
     subArray[subCount] = imageBytes[i]; 
     subCount++; 
     if (i% dimWidth == 0) { 
      subArray = reverse(subArray); 
      if (i == (dimWidth)) { 
       holder = subArray; 
      } else { 
       holder = concat(holder, subArray); 
      } 
      subCount = 0; 
      subArray = new byte[dimWidth]; 
     } 
    } 
    subArray = new byte[dimWidth]; 
    System.arraycopy(imageBytes, imageBytes.length - dimWidth, subArray, 0, subArray.length); 
    holder = concat(holder, subArray); 
    imageBytes = holder; 
    return imageBytes; 
} 
+0

A więc, co wiadomo? –

+0

@HovercraftFullOfEels mówiąc ściśle, mam wysokie bajty i małe bajty w ich własnych tablicach przed ich przeplataniem. Prawie wszystko, co wiadomo, to tablica danych pikseli i tablica danych zawierająca pierwotne informacje wstępnej kompresji. – Sarah

+1

"ale wysokość i szerokość obrazu nie jest znana" To sprawia, że ​​nie wiadomo, gdzie zamieniać piksele (chyba że wysokość i szerokość są liczbą pierwszą, a wiesz, która jest większa). –

Odpowiedz

1

Nevermind chłopaki, mam to działa. Po prostu musiałem odwrócić wysokie i niskie bajty PRZED umieszczeniem ich w ostatecznej tablicy. Dla każdego, kto ma taki sam problem jak ja, użyj powyższej funkcji klapki oddzielnie dla macierzy wysokich i niskich bajtów przed ich przeplataniem.

Dziękuję za pomoc!

+0

upvoted plus-1 do rozwiązania własnego problemu. –

0

zostały również spojrzał konwersji tablicy bajtów do BufferedImage , następnie odwrócenie, ale wysokość i szerokość obrazu nie jest znane w obecnym kontekście.

Możesz po prostu sprawdzić szerokość wysokość & bezpośrednio z sekcji nagłówka JP2 bajtów plików.

import java.io.IOException; 
import java.io.FileInputStream; 
import java.io.File; 

import java.nio.ByteBuffer; 
import javax.xml.bind.DatatypeConverter; 


public class parse_Header_JP2 
{ 
    static File  myFile;  static FileInputStream fileInStream = null; 
    static byte[] myBytes; static String   myString = ""; 

    static int myNum = 0; static int myWidth = 0; static int myHeight = 0; 
    static ByteBuffer byteBuff; 

    public static void main(String[] args) 
    { 
     myFile = new File("c:/test/image.jp2"); 
     myBytes = getBytes_Header_JP2(myFile); 
     checkBytes_Header_JP2(myBytes); //# update myWidth & myHeight 

     //# Shows HEX of whole bytearray 
     System.out.println("First 64 bytes (as HEX) : \n" + bytesToHex(myBytes)); 
    } 

    private static byte[] getBytes_Header_JP2(File file) 
    { 
     myBytes = new byte[64]; //will hold first 64 bytes of file as header bytes 

     try 
     { 
      //# convert file into array of bytes 
      fileInStream = new FileInputStream(file); 
      fileInStream.read(myBytes, 0, 64); //# Read only first 64 bytes 
      fileInStream.close(); 
     } 
     catch (Exception e) { e.printStackTrace(); } //# error catching 

     byteBuff = ByteBuffer.wrap(myBytes); //associate ByteBuffer with bytes 

     return myBytes; 
    } 

    public static void checkBytes_Header_JP2(byte[] bytes) 
    { 
     int offset = 0; myHeight = 0; myWidth = 0; // resets 

     while(true) 
     { 
      //# set as byte value reading from offset 
      myNum = bytes[offset]; myString = Integer.toHexString(myNum).toUpperCase(); 

      //# Check byte as : Hex value 
      System.out.println("Byte Value at [" + offset + "] : " + decimalToHex(myNum)); 

      //# Check byte as : Decimal value 
      //System.out.println("Byte Value at [" + offset + "] : " + myNum); 

      //# Find byte 0x69 (or Decimal = 105) which is letter "i" from "ihdr" 
      if (myNum == 0x69) //# if "i" is found at this offset within bytes 
      { 
       //# From this offset check if reading 4 bytes gives "ihdr" (as bytes 69-68-64-72) 
       if (byteBuff.getInt(offset) == 0x69686472) //# if the 4 bytes make "ihdr" 
       { 
        System.out.println("found \"ihdr\" section at offset : " + offset); 

        //# extract Width or Height from this offset 
        myHeight = byteBuff.getInt(offset+4); //# +4 from "ihdr" is Height entry 
        myWidth = byteBuff.getInt(offset+8); //# +8 from "ihdr" is Width entry 

        //# check values 
        System.out.println("Image Width : " + myWidth); 
        System.out.println("Image Height : " + myHeight); 

        break; //# end the While loop (otherwise runs forever) 
       }  
      }  

      offset++; //# increment offset during While loop process 
     }  
    } 

    //# Convert byte values to Hex string for checking 
    private static String bytesToHex(byte[] bytes) 
    { myString = ""; myString = DatatypeConverter.printHexBinary(bytes); return myString; } 

    private static int bytesToNumber(ByteBuffer input) //throws IOException 
    { input.rewind(); myNum = input.getInt(); return myNum; } 

    private static String decimalToHex(int input) 
    { 
     input = input & 0xFF; myString = Integer.toHexString(input); 
     if(myString.length() == 1) {myString="0"+myString;} 
     return myString.toUpperCase(); 
    } 
} //end Class