Android Bitmap Config类型以及像素数据的读取和反向创建

一次开发中需要在Android平台中进行图像解析相关的开发,于是就研究了Bitmap相关的一些知识。首先了解到,Bitmap创建的时候,Bitmap有些不同类型,类型的定义如下:

  public static enum Config {
        ALPHA_8,
        /** @deprecated */
        @Deprecated
        ARGB_4444,
        ARGB_8888,
        HARDWARE,
        RGBA_F16,
        RGB_565;

        private Config() {
        }
    }

这里定义了好几个类型,先说一下常用的类型:

枚举值

Bitmap.Config  ALPHA_8

每个像素存储为单个半透明(alpha)通道。 每个像素需要1个字节的内存,只保存透明度,不保存颜色。似乎很不常用,应该是只存储ALPHA通道的一种遮罩类型图。创建此类型图后,无法在上面画颜色。

Bitmap.Config  ARGB_4444

每个像素存储在2个字节上,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位,此字段在API级别13中已弃用。由于此类型的图片配置导致画质质量较差,建议使用此字段ARGB_8888。  

Bitmap.Config  ARGB_8888

每个像素存储在4个字节上。即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位。 每个通道(RGB和alpha为半透明)以8位精度(256个可能值)存储。这种配置非常灵活,可提供最佳质量。应尽可能使用它。

Bitmap.Config  HARDWARE

特殊配置,位图仅存储在图形内存中。 

Bitmap.Config  RGBA_F16

每个像素存储在8个字节上。每个通道(RGB和半透明的alpha)存储为半精度浮点值。此配置特别适用于宽色域和HDR内容。

Bitmap.Config  RGB_565

每个像素存储在2个字节上,只有RGB通道被编码:红色以5位精度存储(32个可能值),绿色存储6位精度(64个可能值),蓝色存储5位精确。 此配置可能会产生轻微的视觉瑕疵,具体取决于源的配置。例如,没有抖动,结果可能会显示绿色。为了获得更好的结果,应该应用抖动。当使用不需要高色彩保真度的不透明位图时,此配置可能很有用。

像素值的获取和存储结构:

        //创建10x10的位图
        Bitmap bmp = Bitmap.createBitmap(10,10,Bitmap.Config.ARGB_8888);
        //背景填充白色
        bmp.eraseColor(Color.WHITE);
        //创建存储像素的数组
        int pixels[] = new int[bmp.getWidth() * bmp.getHeight()];
        //取得像素数据
        bmp.getPixels(pixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());

pixels即是我们取到的图像数据,虽然是length=100的一维数组,但是我们也可以理解为是10x10的图片。实际内存中存储的数据是这样的:

每个像素的位置其实都存储了ARGB的值,我们刚才已经把图片涂成了白色,实际的ARGB数值如下图:

发现每一个像素点的值都是-1,并不是白色的255值,那么怎么获取ARGB的值呢?通过以下代码:

        for (int i = 0; i < pixels.length; i++) {
            int a = Color.alpha(pixels[i]);
            int r = Color.red(pixels[i]);
            int g = Color.green(pixels[i]);
            int b = Color.blue(pixels[i]);
        }

可以得出a = 255,r = 255, g = 255, b = 255就得到真实值了,如果是没有ALPHA通道的图片类型如RGB565,就没有alpha的值了。

这就是Android bitmap的存储数据的格式。其实有时候想处理8位灰度图片,也就是一个像素值代表0~255灰度亮度的图片,发现Android里面并没有这种类型,都是彩色RGB三色的图。所以如果需要表示灰度图,只能单独去设置某一个像素r=g=b=0~255就可以了。

同样的道理,通过创建pixels数组,也可以反向创建图片。Bitmap.createBitmap有这样的参数可以使用。

int width = 10;
int height = 10;
int pixels[] = new int[width * height];
for (int i = 0; i < pixels.length; i++) {
    pixels[i] = Color.argb(255, 255, 255, 255);
}
Bitmap bmp = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);

这样就反向创建了白色的图片。

发布了14 篇原创文章 · 获赞 7 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/wangmy1988/article/details/83343200