我正在尝试将带有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;
}
}
出于调试原因,正在将字节数组发送到远程服务器。 当我在服务器中重建位图时,我得到的图像都是像素化的并且在灰度级中具有奇怪的值。 知道我做错了什么吗? 任何评论将不胜感激。 感谢
答案 0 :(得分:0)
O.K,找到了问题的根源,并找到了一个不同且不易出错的解决方案。
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的方式太慢了。