随笔博文

Android中Bitmap.Config

2022-11-26 21:34:00 michael007js 401
  public enum Config {
      ALPHA_8     (1),
      RGB_565     (3),
      @Deprecated
    ARGB_4444   (4),
     ARGB_8888   (5),
     RGBA_F16    (6),
     HARDWARE    (7);
  }

枚举值:

ALPHA_8 每个像素存储为单个半透明(alpha)通道。 每个像素需要1个字节的内存,只保存透明度,不保存颜色。似乎很不常用,应该是只存储ALPHA通道的一种遮罩类型图。创建此类型图后,无法在上面画颜色。
RGB_565 每个像素存储在2个字节上,只有RGB通道被编码:红色以5位精度存储(32个可能值),绿色存储6位精度(64个可能值),蓝色存储5位精确。 此配置可能会产生轻微的视觉瑕疵,具体取决于源的配置。例如,没有抖动,结果可能会显示绿色。为了获得更好的结果,应该应用抖动。当使用不需要高色彩保真度的不透明位图时,此配置可能很有用。
ARGB_4444 每个像素存储在2个字节上,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位,此字段在API级别13中已弃用。由于此类型的图片配置导致画质质量较差,建议使用此字段ARGB_8888。
ARGB_8888 每个像素存储在4个字节上。即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位。 每个通道(RGB和alpha为半透明)以8位精度(256个可能值)存储。这种配置非常灵活,可提供最佳质量。应尽可能使用它。
RGBA_F16 每个像素存储在8个字节上。每个通道(RGB和半透明的alpha)存储为半精度浮点值。此配置特别适用于宽色域和HDR内容。
HARDWARE 特殊配置,位图仅存储在图形内存中。

RGB_565简介:

RGB_565是色彩压缩的一种方式,其通过不用透明率以及对RGB的相应位数进行省略。 一个彩色图像由R G B三个分量组成,一个RGB565的每一个像素点数据为2Byte,即16位,那么从名字上就可看出来这16位中,高5位为R分量,中间6位为G分量,低5位为B分量。

图片关键词

相应的还有一些色彩存储方式:

ALPHA_8 代表8位Alpha位图 ARGB_4444 代表16位ARGB位图 ARGB_8888 代表32位ARGB位图 RGB_565 代表16位RGB位图

A:透明度(Alpha) R:红色(Red) G:绿(Green) B:蓝(Blue)

  1. .Config ARGB_8888:由4个8位组成,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位(4字节)
  2. Bitmap.Config ARGB_4444:由4个4位组成,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位 (2字节)
  3. Bitmap.Config RGB_565:没有透明度,R=5,G=6,B=5,,那么一个像素点占5+6+5=16位(2字节)
  4. Bitmap.Config ALPHA_8:每个像素占8位,只有透明度,没有颜色。

一般情况下我们使用的色彩模式为ARGB_8888,这种模式下一个像素所占的大小为4字节,一个像素的位数总和越高,图像也就越逼真。

假设有一张480x800的图片: 在色彩模式为ARGB_8888的情况下,会占用 4808004/1024KB=1500KB 的内存; 而在RGB_565的情况下,占用的内存为:4808002/1024KB=750KB。

Glide的解码格式是RGB565,Picasso是ARGB8888 ,所以同一个图片,picasso更清晰,但是更耗内存。

    public void getBitmap(View view) {
        //创建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());
        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]);
            Log.i("MainActivity i = ", i+"");
            Log.i("MainActivity a = ", a+"");
            Log.i("MainActivity r = ", r+"");
            Log.i("MainActivity g = ", g+"");
            Log.i("MainActivity b = ", b+"");
        }
    }

打印结果如下:图片关键词

可以得出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有这样的参数可以使用。

生成一张黑色的图片:

    public void createBitmap(View view) {
        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, 0, 0, 0);//全黑色
        }
        Bitmap bmp = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
        imgv.setImageBitmap(bmp);
    }

在这里插入图片描述

首页
关于博主
我的博客
搜索