Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/217.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android图像表示_Android_Image_Pixels - Fatal编程技术网

Android图像表示

Android图像表示,android,image,pixels,Android,Image,Pixels,我正在尝试访问Android中图像的原始像素数据。 代码如下所示: Bitmap bitmap = BitmapFactory.decodeFile("image.png"); // assert valid input if ((bitmap.getConfig() == null) || bitmap.getConfig() == Config.ARGB_8888) throw new Exception("bad config"); ByteBuff

我正在尝试访问Android中图像的原始像素数据。
代码如下所示:

   Bitmap bitmap =  BitmapFactory.decodeFile("image.png"); 
   // assert valid input
   if ((bitmap.getConfig() == null) || bitmap.getConfig() == Config.ARGB_8888)
      throw new Exception("bad config");

  ByteBuffer buffer = ByteBuffer.allocate(4 * bitmap.getWidth() * bitmap.getHeight());
  bitmap.copyPixelsToBuffer(buffer);        
  return buffer.array();
线性1D
buffer.array()中的像素是如何存储的

  • 第一个元素是左上像素还是左下像素(或其他)
  • 行主要(行后的行)还是列主要(列后的列)
  • 频道订单ARGB还是BGRA
  • 每个频道分别采用行主频道还是列主频道
  • 别的

  • 要在大小为
    width
    x
    height
    且每像素字节数为
    bytesperpoixel
    的图像中获得给定像素
    x
    y
    的偏移量,请使用以下公式:

    offsetForPixel = (y * width + x) * bytesPerPixel
    
    换句话说,数组中的第一个元素是左上角的像素,下面的元素是行主元素。一个像素的所有数据都存储在相邻的字节中,并且不会基于通道展开。这是上面1、2和4的答案。现在让我们讨论3,这是事情变得复杂的地方

    copyPixelsToBuffer()是Android的低级绘图库使用的原始位图数据表示形式。这有三个重要后果:

    • 通道顺序取决于端度
    • 通道与alpha进行预乘
    • 如何将通道打包为包含数据类型是可配置的
    最后一点是,如果您想检查单个像素,就很难使用
    Bitmap.copyPixelsToBuffer()
    ,因为您根本不知道skia是如何配置为打包通道的。作为实验,请尝试以下代码:

    int inputPixel = 0x336699cc;
    int[] pixels = new int[] { inputPixel };
    Bitmap bm = Bitmap.createBitmap(pixels, 1, 1, Config.ARGB_8888);
    ByteBuffer bb = ByteBuffer.allocate(4);
    bm.copyPixelsToBuffer(bb);
    Log.i("TAG", "inputPixel = 0x" + Integer.toHexString(inputPixel));
    for (int i = 0; i < 4; i++) {
        String byteString = "0x" + Integer.toHexString(bb.array()[i] & 0xff);
        Log.i("TAG", "outputPixel byte " + i + " = " + byteString);
    }
    
    我们可以看到,我们正在处理big-endian,内存中的表示是预乘的,通道已经从ARGB重新排列到RGBA(在skia源代码中,它的动机是内存中的表示与OpenGL相同)

    如果您想读取像素数据,我建议您使用。需要进行一些复制,但至少API指定了返回数据的格式

    I/TAG ( 1995): inputPixel = 0x336699cc
    I/TAG ( 1995): outputPixel byte 0 = 0x14
    I/TAG ( 1995): outputPixel byte 1 = 0x1f
    I/TAG ( 1995): outputPixel byte 2 = 0x29
    I/TAG ( 1995): outputPixel byte 3 = 0x33