【问题标题】:Flip an image stored as a byte array翻转存储为字节数组的图像
【发布时间】:2017-01-09 16:49:53
【问题描述】:

我有一个存储为 byte[] 数组的图像,我想在将字节写入其他位置之前垂直翻转图像。

图像字节来自压缩的 jp2 图像文件。我已经研究过实现类似Flip image stored as a byte[] array 的东西,但我不在android 中工作,也无权访问BitmapFactory。我还研究过先将字节数组转换为 BufferedImage,然后翻转它,但是在当前上下文中不知道图像的高度和宽度(编辑:我已经修改了代码,因此高度和宽度是现在已知)。

有没有办法只通过严格的数组操作来做到这一点?

编辑:尝试翻转代码

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

【问题讨论】:

  • 那么我们知道什么?
  • @HovercraftFullOfEels 严格来说,在交错它们之前,我在它们自己的数组中有高字节和低字节。几乎所有已知的都是像素数据数组和一个包含原始预压缩头信息的数据数组。
  • "但图像的高度和宽度未知" 这使得无法知道在哪里交换像素(除非高度和宽度是素数,并且你知道哪个更大)。
  • @AndyTurner 这就是我害怕的。好吧,如果不可能,那就不可能了。我会尝试想出一个不同的解决方案来解决我的问题。谢谢!
  • 我猜你需要一个库来将 jp2 压缩转换为未压缩的图像。这是否存在,我不知道。

标签: java arrays image byte


【解决方案1】:

没关系,伙计们,我得到了它的工作。在将它们交错到最终数组之前,我只需要翻转高字节和低字节。对于和我有同样问题的人,请在交错之前分别对高字节和低字节数组使用上述翻转函数。

感谢您的帮助!

【讨论】:

    【解决方案2】:

    我还研究了将字节数组转换为BufferedImage 首先,然后翻转它,但图像的 heightwidth 不是 在当前上下文中已知。

    您可以直接从 JP2 文件字节的标题部分检查高度和宽度。

    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
    

    【讨论】:

      猜你喜欢
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-26
      • 2019-04-16
      • 1970-01-01
      • 2018-02-12
      • 1970-01-01
      • 2012-04-29
      相关资源
      最近更新 更多