1

我正在尝试将具有 ARGB_8888 格式的位图转换为需要在应用程序的本机部分中使用的单通道字节数组。

我使用

int pixel = bitmap.getPixel(x,y);
 int redValue = Color.red(pixel);
 int blueValue = Color.blue(pixel);
 int greenValue = Color.green(pixel);
 int alphaValue = Color.alpha(pixel);

而且看起来格式实际上是RGBA而不是ARGB。

我用下面的代码来完成这个任务

public static byte[] bitmapToByteArray(Bitmap bm) {
        // Create the buffer with the correct size
        int iBytes = bm.getWidth() * bm.getHeight() ;
        byte[] res = new byte[iBytes];
        Bitmap.Config format = bm.getConfig();
        if (format == Bitmap.Config.ARGB_8888)
        {
            ByteBuffer buffer = ByteBuffer.allocate(iBytes*4);
            // Log.e("DBG", buffer.remaining()+""); -- Returns a correct number based on dimensions
            // Copy to buffer and then into byte array
            bm.copyPixelsToBuffer(buffer);
            byte[] arr = buffer.array();
            for(int i=0;i<iBytes;i++)
            {
                int A,R,G,B;
                R=(int)(arr[i*4+0]) & 0xff;
                G=(int)(arr[i*4+1]) & 0xff;
                B=(int)(arr[i*4+2]) & 0xff;
                //A=arr[i*4+3];
                byte r = (byte)(0.2989 * R + 0.5870 * G + 0.1140 * B) ;
                res[i] = r;
            }
        }
        if (format == Bitmap.Config.RGB_565)
        {
            ByteBuffer buffer = ByteBuffer.allocate(iBytes*2);
            // Log.e("DBG", buffer.remaining()+""); -- Returns a correct number based on dimensions
            // Copy to buffer and then into byte array
            bm.copyPixelsToBuffer(buffer);
            byte[] arr = buffer.array();
            for(int i=0;i<iBytes;i++)
            {
                float A,R,G,B;
                R = ((arr[i*2+0] & 0xF8) );
                G = ((arr[i*2+0] & 0x7) << 5) + ((arr[i*2+1] & 0xE0) >> 5);
                B = ((arr[i*2+1] & 0x1F) << 3 );
                byte r = (byte)(0.2989 * R + 0.5870 * G + 0.1140 * B) ;
                res[i] = r;
            }
        }
        // Log.e("DBG", buffer.remaining()+""); -- Returns 0
        return res;
    }
}

出于调试原因,正在将字节数组发送到远程服务器。当我在服务器中重建位图时,我得到的图像都是像素化的,并且灰度值很奇怪。知道我做错了什么吗?任何评论将不胜感激。谢谢

4

1 回答 1

0

好的,找到了问题的根源,找到了一个与众不同且不易出错的解决方案。

1) 像素化暗图像是由于输入图像是 RGB565 格式,并且恢复 RGB 被搞砸了……请参阅以下本机代码,我现在使用以下本机代码来查看差异:

> void MYJNI::ConvertRGBToGRAY(unsigned char in[], unsigned char
> out[],int w,int h,int type)
>     {
>       int sz = w*h;
>       char msg[300];
>       sprintf(msg,"width = %u height = %u sz = %u",w,h,sz);
>     #if defined(__ANDROID__) || defined(ANDROID)
>       __android_log_write(ANDROID_LOG_INFO,"MOBLINK", msg);
>     #endif
>       if (type == 0) //RGBA
>       {
>           for(int i=0;i<sz;i++)
>           {
>               float A,R,G,B;
>               R=in[i*4+0];
>               G=in[i*4+1];
>               B=in[i*4+2];
>               //A=arr[i*4+3];
>               unsigned char ir = 0.2989 * R + 0.5870 * G + 0.1140 * B;
>               out[i] = ir;
>           }
>       }
>       else if(type == 1) //RGB565
>       {
>           uint16_t *parr = (uint16_t*)in;
>           for(int i=0;i<sz;i++)
>           {
>               float A,R,G,B;
>               R = ((parr[i] & 0xF800)>> 11) *8;
>               G = ((parr[i] & 0x07e0)>> 5) *4;
>               B = ((parr[i] & 0x001F)>> 0) *8;
>               
>               unsigned char ir = 0.2989 * R + 0.5870 * G + 0.1140 * B;
>               out[i] = ir;
>           }
>       }
>     } 

我使用本机函数,因为基于 java 的速度太慢了。

于 2013-07-01T06:25:27.663 回答