GOOGLE对于图像的读取处理,已经封装了Bitmap类和BitmapFactory类,可以说囊括了许多种读取图片数据的方式,
但是如果我们通过图片解码得到纯RGB数据(byte[])和位图宽和高,又当如何将数据上屏显示呢?
查看SDK文档,其中BitmapFactory.decodeByteArray(byte[]data,intoffset,intlength),不要鸡动,该byte[]针对的是完整的图片数据,包括文件头那些东东,所以不符要求
再看Bitmap.createBitmap(int[]colors,intoffset,intstride,intwidth,intheight,Bitmap.Configconfig),这个很接近了,我们要做的就是将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
有兴趣的童鞋下载下来看看吧