• Bitmap.Config 说明 ALPHA_8 ARGB_4444 ARGB_8888 RGB_565


    这篇文章的目的是了解Bitmap.Config

    你可以在使用这个方法的时候会遇到

    Bitmap android.graphics.Bitmap.createBitmap(int width, int height, Config config)

    需要一个Bitmap 然后在上面画一些东西。

    Bitmap 构造方法很多:

    几个都带有Config这个参数。这个参数倒底是什么?

    看一下源码:

     /**
         * Possible bitmap configurations. A bitmap configuration describes
         * how pixels are stored. This affects the quality (color depth) as
         * well as the ability to display transparent/translucent colors.
         */
        public enum Config {
            // these native values must match up with the enum in SkBitmap.h
    
            /**
             * Each pixel is stored as a single translucency (alpha) channel.
             * This is very useful to efficiently store masks for instance.
             * No color information is stored.
             * With this configuration, each pixel requires 1 byte of memory.
             */
            ALPHA_8     (1),
    
            /**
             * Each pixel is stored on 2 bytes and only the RGB channels are
             * encoded: red is stored with 5 bits of precision (32 possible
             * values), green is stored with 6 bits of precision (64 possible
             * values) and blue is stored with 5 bits of precision.
             *
             * This configuration can produce slight visual artifacts depending
             * on the configuration of the source. For instance, without
             * dithering, the result might show a greenish tint. To get better
             * results dithering should be applied.
             *
             * This configuration may be useful when using opaque bitmaps
             * that do not require high color fidelity.
             */
            RGB_565     (3),
    
            /**
             * Each pixel is stored on 2 bytes. The three RGB color channels
             * and the alpha channel (translucency) are stored with a 4 bits
             * precision (16 possible values.)
             *
             * This configuration is mostly useful if the application needs
             * to store translucency information but also needs to save
             * memory.
             *
             * It is recommended to use {@link #ARGB_8888} instead of this
             * configuration.
             *
             * Note: as of {@link android.os.Build.VERSION_CODES#KITKAT},
             * any bitmap created with this configuration will be created
             * using {@link #ARGB_8888} instead.
             *
             * @deprecated Because of the poor quality of this configuration,
             *             it is advised to use {@link #ARGB_8888} instead.
             */
            @Deprecated
            ARGB_4444   (4),
    
            /**
             * Each pixel is stored on 4 bytes. Each channel (RGB and alpha
             * for translucency) is stored with 8 bits of precision (256
             * possible values.)
             *
             * This configuration is very flexible and offers the best
             * quality. It should be used whenever possible.
             */
            ARGB_8888   (5);
    
            final int nativeInt;
    
            private static Config sConfigs[] = {
                null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
            };
    
            Config(int ni) {
                this.nativeInt = ni;
            }
    
            static Config nativeToConfig(int ni) {
                return sConfigs[ni];
            }
        }

    第一眼看上去应是个类类型,上来new一个吧。但是不行。

    点进去看是枚举类型。

    再仔细看一下源码:

        public enum Config {
           
            ALPHA_8     (1),
            @Deprecated
            ARGB_4444   (4),
            ARGB_8888   (5);
    
            final int nativeInt;
    
            private static Config sConfigs[] = {
                null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
            };
    
            Config(int ni) {
                this.nativeInt = ni;
            }
            static Config nativeToConfig(int ni) {
                return sConfigs[ni];
            }
        }

    有点蒙逼吧。这语言平见也少用。其实枚举类型类似于常量,直接用就行。如下:

    Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);

    好吧,枚举这东西用得少,可以复习一下。

    https://www.cnblogs.com/happyPawpaw/archive/2013/04/09/3009553.html

    顺便多说两句,为什么要用枚举。

    枚举在java1.5以后才推荐使用。

    1.switch

    JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。

    2.使用static final int 来定义常量同样可以实现逻辑,为什么搞个枚举出来

      速度更快:

      1 作者:ccloomi
      2 链接:https://www.zhihu.com/question/48915384/answer/151489315
      3 来源:知乎
      4 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
      5 
      6 事实上使用枚举类型的性能几乎是使用静态类的16倍,至于为什么我们看代码,这里我写了两个类,Age类是一个枚举类型public enum Age {
      7     _12,_16,_19
      8 }
      9 AG类是一个静态类public class AG {
     10     public static final int _12=12;
     11     public static final int _16=16;
     12     public static final int _19=19;
     13 }
     14 然后是一个测试Main类public class Main {
     15     public void age(Age ag){
     16         switch (ag) {
     17         case _12:
     18             break;
     19         case _16:
     20             break;
     21         case _19:
     22             break;
     23         default:
     24             break;
     25         }
     26     }
     27     public void age(int ag){
     28         switch (ag) {
     29         case 12:
     30             break;
     31         case 16:
     32             break;
     33         case 19:
     34             break;
     35         default:
     36             break;
     37         }
     38     }
     39     public static void main(String[] args) {
     40         long t=0,limit=1000000;
     41         Main mm=new Main();
     42         
     43         t=System.currentTimeMillis();
     44         for(long i=0;i<limit;i++){
     45             mm.age(Age._16);
     46         }
     47         System.out.println("耗时"+(System.currentTimeMillis()-t)+"ms");
     48         
     49 
     50         t=System.currentTimeMillis();
     51         for(long i=0;i<limit;i++){
     52             mm.age(16);
     53         }
     54         System.out.println("耗时"+(System.currentTimeMillis()-t)+"ms");
     55     }
     56 }
     57 同样的方法我们执行100万此,执行结果耗时0ms
     58 耗时16ms
     59 使用枚举类的方法秒杀了静态类,至于为什么我们可以看Main这个方法编译后生成的字节码 // access flags 0x1
     60   public age(Lcom/test/en/Age;)V
     61    L0
     62     LINENUMBER 11 L0
     63     INVOKESTATIC com/test/en/Main.$SWITCH_TABLE$com$test$en$Age ()[I
     64     ALOAD 1
     65     INVOKEVIRTUAL com/test/en/Age.ordinal ()I
     66     IALOAD
     67     TABLESWITCH
     68       1: L1
     69       2: L2
     70       3: L3
     71       default: L4
     72    L1
     73     LINENUMBER 13 L1
     74    FRAME SAME
     75     GOTO L4
     76    L2
     77     LINENUMBER 15 L2
     78    FRAME SAME
     79     GOTO L4
     80    L3
     81     LINENUMBER 17 L3
     82    FRAME SAME
     83     GOTO L4
     84    L4
     85     LINENUMBER 21 L4
     86    FRAME SAME
     87     RETURN
     88    L5
     89     LOCALVARIABLE this Lcom/test/en/Main; L0 L5 0
     90     LOCALVARIABLE ag Lcom/test/en/Age; L0 L5 1
     91     MAXSTACK = 2
     92     MAXLOCALS = 2
     93 
     94   // access flags 0x1
     95   public age(I)V
     96    L0
     97     LINENUMBER 23 L0
     98     ILOAD 1
     99     LOOKUPSWITCH
    100       12: L1
    101       16: L2
    102       19: L3
    103       default: L4
    104    L1
    105     LINENUMBER 25 L1
    106    FRAME SAME
    107     GOTO L4
    108    L2
    109     LINENUMBER 27 L2
    110    FRAME SAME
    111     GOTO L4
    112    L3
    113     LINENUMBER 29 L3
    114    FRAME SAME
    115     GOTO L4
    116    L4
    117     LINENUMBER 33 L4
    118    FRAME SAME
    119     RETURN
    120    L5
    121     LOCALVARIABLE this Lcom/test/en/Main; L0 L5 0
    122     LOCALVARIABLE ag I L0 L5 1
    123     MAXSTACK = 1
    124     MAXLOCALS = 2
    125 注意看使用枚举类的方法使用的是TABLESWITCH
    126 使用静态类的方法使用的确是LOOKUPSWITCH
    127 这两个性能差距是很大的
    View Code

     通过注解,来约束一些变量及参数。使的程序在编写之时就变得健壮。

    回到主题:

    看看枚举变量倒底什么含义。
    public static final Bitmap.Config  ALPHA_8 
    public static final Bitmap.Config  ARGB_4444  
    public static final Bitmap.Config  ARGB_8888
    public static final Bitmap.Config  RGB_565 


    ALPHA_8 
    源码注释很清楚:
    /**
    * Each pixel is stored as a single translucency (alpha) channel.
    * This is very useful to efficiently store masks for instance.
    * No color information is stored.
    * With this configuration, each pixel requires 1 byte of memory.
    */
    每个像素只存alpha 通道值,就是透明值。
    Each pixel is stored as a single translucency (alpha) channel
    对处理遮罩很有效,
    No color information is stored.
    没有存颜色值就是说没有rgb信息。 (此处画重点)
    each pixel requires 1 byte of memory
    每个pixel占一个byte.1个字节。
    所以网上很多博文瞎扯的。还是自己看源码靠谱。

    再看下RGB_565
    /**
    * Each pixel is stored on 2 bytes and only the RGB channels are
    * encoded: red is stored with 5 bits of precision (32 possible
    * values), green is stored with 6 bits of precision (64 possible
    * values) and blue is stored with 5 bits of precision.
    *
    * This configuration can produce slight visual artifacts depending
    * on the configuration of the source. For instance, without
    * dithering, the result might show a greenish tint. To get better
    * results dithering should be applied.
    *
    * This configuration may be useful when using opaque bitmaps
    * that do not require high color fidelity.
    */
    每个像素2byte存储空间。
    红:5位(5 bits)对应32色。就是有32种不同的红色。
    绿:green is stored with 6 bits of precision (64 possible)绿 6 位 64色。
    蓝:5位 32色

    自然没有alpha值。看明白了没有透明值。自己去建一个没有透明bitmap试一下吧,看看什么效果。
    最后使用在do not require high color fidelity (图片质量要求不高的场景)

    能表示多少种颜色呢 32*64*32 =65536 色。是不是很熟啊。

    再看下
    ARGB_4444
    /**
    * Each pixel is stored on 2 bytes. The three RGB color channels
    * and the alpha channel (translucency) are stored with a 4 bits
    * precision (16 possible values.)
    *
    * This configuration is mostly useful if the application needs
    * to store translucency information but also needs to save
    * memory.
    *
    * It is recommended to use {@link #ARGB_8888} instead of this
    * configuration.
    *
    * Note: as of {@link android.os.Build.VERSION_CODES#KITKAT},
    * any bitmap created with this configuration will be created
    * using {@link #ARGB_8888} instead.
    *
    * @deprecated Because of the poor quality of this configuration,
    * it is advised to use {@link #ARGB_8888} instead.
    */
    不再多说了,很好理解,共2byte 16位 。4位透明,R,G,B各占四位。

    ARGB_8888   

    顾名思义:A8位,G,R,B各8位。

    32位真彩色是什么意思呢就是这个类型来表示,一共能表示多少种色彩呢
    2^8*2^8*2^8 = 16777216 ;
    这里所说的所有东西都是针对一个像素来讨论的。
    那么一张图,在内存当中占多少内存呢,
    内存=宽*高*每个像素点占的存。
    以argb_8888为例:
    100*100像素的图片在内存中占:100*100*32 bit 0.305M
    看看满屏一张图占多少,1920*1080*32=63.28M
    是不是很恐怖呢63M!!!






  • 相关阅读:
    inner join 与 left join 之间的区别
    pdo Call to a member function setFetchMode() on boolean in
    PHP用星号隐藏用户名中间部分
    phpstorm里面无法配置deployment问题
    替换字符串中间部分为*
    tp3.2中between的用法
    PHP中的$this用法
    PhpStorm中实现代码自动换行
    ORM常用操作介绍
    django的admin的基础配置和使用
  • 原文地址:https://www.cnblogs.com/mamamia/p/7910095.html
Copyright © 2020-2023  润新知