[Android]BitmapのConfigフォーマットの設定とConfigパラメータのソースを修正して読みます.

13389 ワード

BitmapのConfig設定の変更について
オリジナルブログ、転載は出所を明記してください:http://blog.csdn.net/u011035622/article/details/50277565
Bitmap.C.onfigの紹介
まずConfig設定のパラメータを紹介しましょう.読者に分かりやすくする一方で、自分にも印象を与えます.Bitmap.C.onfigは全部で4つのパラメータがあります.
  • Bitmap.Coonfig ALPHA_8このパラメータは各ピクセルに対して1バイトの空間を占有します.各ピクセルポイントが単一の透明度のチャネルとして記憶されていることを表しています.これはカバーを設置する画像の用例にとって非常に有用で、色情報を保存しません.
  • Bitmap.Coonfig RGB_565このパラメータは、各ピクセルに対して2バイトの空間を占有する.これは、RGBチャネルのみの符号化を表しており、赤色は5ビットのアドレスを占め、緑は6ビットのアドレスを占め、青は5ビットのアドレスを占有する.透明度のない通路.不透明なビットマップを使用する場合は、高い色の忠実度を要求しないように設定するのが良いです.
  • Bitmap.Coonfig ARGB_4444このパラメータは、各ピクセルに対して2バイトの空間を占有する.全部で四つの通路があります.その名の通り、透明度、赤、緑、青です.チャネルごとに4ビットのアドレスを占有するので、全部で2バイトです.アプリケーションがメモリを節約する必要がある場合(色の品質に対する要求が低い)、また透明度の情報を保存する必要があります.この構成は選択としてもいいですが、公式の方がARGB_を推奨します.8888の設定は、これの色の品質が悪いからです.
  • Bitmap.Coonfig ARGB_8888このパラメータは各ピクセルに4バイトの空間を占有します.これも全部で4つのチャンネルですが、違うのは各チャンネルの8桁の住所です.色の品質は前の設定よりずっと高いです.(16倍).最適なビットマップ品質を満足させることができます.メモリが十分にある場合、これを使用することをお勧めします.以下の参考文献の公式ソース解釈:
  •     /**
         * 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;
    
            @SuppressWarnings({"deprecation"})
            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のConfig設定を変更します.
    修正時に発生した問題
    もしローカル画像のパスであれば、直接にこのような方法でbitmapを得てOptions.inPreferredConfigを通じて彼のCofigパラメータを設定することができます.
         Bitmap bitmap = null;
         File file = new File(path);
         if(file.exists()) {
             BitmapFactory.Options opts = new BitmapFactory.Options();
             opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
             try {
                 bitmap = BitmapFactory.decodeFile(path, opts);
             } catch (OutOfMemoryError error) {
                 bitmap = null;
             }
         }
    これは特に問題ないです.しかし、Bitmapを持っていますが、彼のConfig設定をどのように修正しますか?Bitmapを見に行くと、setConfigやこのreconfigureに似た方法があります.この方法を見たら直接に呼び出しました.
    bitmap.setConfig(Bitmap.Config.ARGB_8888);
    もちろん跪きます.Android Runtime:FATAL EXCEPTION:main java.lang.NoSuchMethodErr:android.graphics.Bitmap.reconfigre*.
    問題の解決方法
    よく振り回されていますが、どこが間違っているか分かりません.ソースコードを見てから分かります.
    set Config、reconfigur方法は、現在使用されているビットマップには使用できません!!!=.(最後に公式ソースを貼った読者は参考にしてみてもいいです.)
    考えてみると、現在のビットストリームを先にビットストリームに変換し、ビットストリームをBitmapfactoryで設定に従って再生成するしかない.やはり、問題解決:
          /*  bitmap  ,  bitmap。*/
          ByteArrayOutputStream dataByte = new ByteArrayOutputStream();
          bitmap.compress(Bitmap.CompressFormat.PNG, 100, dataByte);
          BitmapFactory.Options opts = new BitmapFactory.Options();
          opts.inSampleSize = OPT_INSAMPLE_SIZE;
          opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
          bitmap = BitmapFactory.decodeByteArray(dataByte.toByteArray(), 0, dataByte.size(), opts);
    何度も経験して教えてくれました.勉強する時にはよくソースコードを見て紹介することが大切です.BitmapとBitmap Factoryのソースコードを探してください.
    最後にsetConfigの公式ソース部分を貼り付けます.
        /**
         * 

    Convenience method for calling {@link #reconfigure(int, int, Config)} with the current height and width.

    *( bitmap=。=) *

    WARNING: this method should not be used on bitmaps currently used by the view system, see {@link #reconfigure(int, int, Config)} for more details. */

    public void setConfig(Config config) { reconfigure(getWidth(), getHeight(), config); }
    reconfigure:
    また、Bitmapの修正はhasalphaに影響を与える可能性があります.つまり、フォーマットの変更は透明な通路があるかないかということです.2、ビットマップの配置があまり大きくない場合、新しい構成をサポートします.ILL Argement Exceptionは抛り出します.ビットマップは修正されません.
        /**
         * 

    Modifies the bitmap to have a specified width, height, and {@link * Config}, without affecting the underlying allocation backing the bitmap. * Bitmap pixel data is not re-initialized for the new configuration.

    * *

    This method can be used to avoid allocating a new bitmap, instead * reusing an existing bitmap's allocation for a new configuration of equal * or lesser size. If the Bitmap's allocation isn't large enough to support * the new configuration, an IllegalArgumentException will be thrown and the * bitmap will not be modified.

    * *

    The result of {@link #getByteCount()} will reflect the new configuration, * while {@link #getAllocationByteCount()} will reflect that of the initial * configuration.

    * *

    Note: This may change this result of hasAlpha(). When converting to 565, * the new bitmap will always be considered opaque. When converting from 565, * the new bitmap will be considered non-opaque, and will respect the value * set by setPremultiplied().

    * *

    WARNING: This method should NOT be called on a bitmap currently used * by the view system. It does not make guarantees about how the underlying * pixel buffer is remapped to the new config, just that the allocation is * reused. Additionally, the view system does not account for bitmap * properties being modifying during use, e.g. while attached to * drawables.

    * * @see #setWidth(int) * @see #setHeight(int) * @see #setConfig(Config) */ public void reconfigure(int width, int height, Config config) { checkRecycled("Can't call reconfigure() on a recycled bitmap"); if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width and height must be > 0"); } if (!isMutable()) { throw new IllegalStateException("only mutable bitmaps may be reconfigured"); } if (mBuffer == null) { throw new IllegalStateException("native-backed bitmaps may not be reconfigured"); } nativeReconfigure(mNativeBitmap, width, height, config.nativeInt, mBuffer.length, mRequestPremultiplied); mWidth = width; mHeight = height; }