GOOGLE对于图像的读取处理,已经封装了Bitmap类和BitmapFactory类,可以说囊括了许多种读取图片数据的方式,
但是如果我们通过图片解码得到纯RGB数据(byte[])和位图宽和高,又当如何将数据上屏显示呢?
查看SDK文档,其中 BitmapFactory.decodeByteArray(byte[] data, int offset, int length),不要鸡动,该byte[]针对的是完整的图片数据,包括文件头那些东东,所以不符要求
再看 Bitmap.createBitmap(int[] colors, int offset, int stride, int width, int height, Bitmap.Config config) ,这个很接近了,我们要做的就是将byte[]data转化为int[]color
先看下效果图:
第一张图是直接读取资源文件里的图片然后显示
第二张图是提取该图片中的RGB数组以及位图宽高,以此作为数据源重新创建一张位图然后显示出来
下面贴上代码:
public class DrawBitmapByRgbActivity extends Activity { /** Called when the activity is first created. */ private MyView mMyView1; private MyView mMyView2; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initView(); initLogic(); } public void initView() { mMyView1 = (MyView) findViewById(R.id.myview1); mMyView2 = (MyView) findViewById(R.id.myview2); } public void initLogic() { Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.test); mMyView1.setBitmap(bitmap1); // 获取该位图的RGB数据 byte[]rgbData = MyUtil.getRGBByBitmap(bitmap1); // 根据该RGB数组生成位图 Bitmap bitmap2 = MyBitmapFactory.createMyBitmap(rgbData, bitmap1.getWidth(), bitmap1.getHeight()); mMyView2.setBitmap(bitmap2); }
public class MyUtil { /* * 获取位图的RGB数据 */ public static byte[] getRGBByBitmap(Bitmap bitmap) { if (bitmap == null) { return null; } int width = bitmap.getWidth(); int height = bitmap.getHeight(); int size = width * height; int pixels[] = new int[size]; bitmap.getPixels(pixels, 0, width, 0, 0, width, height); byte[]data = convertColorToByte(pixels); return data; } /* * 像素数组转化为RGB数组 */ public static byte[] convertColorToByte(int color[]) { if (color == null) { return null; } byte[] data = new byte[color.length * 3]; for(int i = 0; i < color.length; i++) { data[i * 3] = (byte) (color[i] >> 16 & 0xff); data[i * 3 + 1] = (byte) (color[i] >> 8 & 0xff); data[i * 3 + 2] = (byte) (color[i] & 0xff); } return data; } }
public class MyBitmapFactory { /* * byte[] data保存的是纯RGB的数据,而非完整的图片文件数据 */ static public Bitmap createMyBitmap(byte[] data, int width, int height){ int []colors = convertByteToColor(data); if (colors == null){ return null; } Bitmap bmp = null; try { bmp = Bitmap.createBitmap(colors, 0, width, width, height, Bitmap.Config.ARGB_8888); } catch (Exception e) { // TODO: handle exception return null; } return bmp; } /* * 将RGB数组转化为像素数组 */ private static int[] convertByteToColor(byte[] data){ int size = data.length; if (size == 0){ return null; } // 理论上data的长度应该是3的倍数,这里做个兼容 int arg = 0; if (size % 3 != 0){ arg = 1; } int []color = new int[size / 3 + arg]; int red, green, blue; if (arg == 0){ // 正好是3的倍数 for(int i = 0; i < color.length; ++i){ color[i] = (data[i * 3] << 16 & 0x00FF0000) | (data[i * 3 + 1] << 8 & 0x0000FF00 ) | (data[i * 3 + 2] & 0x000000FF ) | 0xFF000000; } }else{ // 不是3的倍数 for(int i = 0; i < color.length - 1; ++i){ color[i] = (data[i * 3] << 16 & 0x00FF0000) | (data[i * 3 + 1] << 8 & 0x0000FF00 ) | (data[i * 3 + 2] & 0x000000FF ) | 0xFF000000; } color[color.length - 1] = 0xFF000000; // 最后一个像素用黑色填充 } return color; } }
基本上就是这样了,一个像素占4个字节,即ARGB,对于像素的拆解与组合无非就是一些位运算
比如要设置某个像素半透明的话,只要int & 0x00ffffff | 0x80000000 即可
附上工程链接:
http://download.csdn.net/detail/geniuseoe2012/4388433