美文网首页
Android Bitmap优化

Android Bitmap优化

作者: Zachary46 | 来源:发表于2021-11-03 14:29 被阅读0次

    Bitmap 的采样压缩(这个采样率是根据需求来进行生成的),使用到了inBitmap内存复用和 inJustDecodeBounds 。

    采样的流程:
    1. 将 BitmapFactory.Options 的 inJustDecodeBounds 参数设置为 true 并加装图片。
    2. 从 BitmapFactory.Options 中取出图片的原始宽和高,它们对应于 outWidth 和 outHeight 参数。
    3. 根据采样率的规则并结合目标 View 的所需要大小计算出采样率 inSampleSize 。
    4. 将 BitmapFactory.Options 的 inJustDecodeBounds 参数设为 false ,然后重新加装图片。
       /**
         * 采样率压缩,这个和矩阵来实现缩放有点类似,但是有一个原则是“大图小用用采样,小图大用用矩阵”。
         * 也可以先用采样来压缩图片,这样内存小了,可是图的尺寸也小。如果要是用 Canvas 来绘制这张图时,再用矩阵放大
         * @param image Bitmap
         * @param compressFormat Bitmap.CompressFormat.JPEG
         * @param requestWidth 要求的宽度
         * @param requestHeight 要求的长度
         * @return
         */
        public static Bitmap compressbySample(Bitmap image, Bitmap.CompressFormat compressFormat, int requestWidth, int requestHeight){
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            image.compress(compressFormat, 80, baos);//0~100质量压缩方法,这里80表示80%不压缩,压缩20%,把压缩后的数据存放到baos中
            ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
    
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.RGB_565;//建议使用
            options.inPurgeable = true;
            options.inJustDecodeBounds = true;//只读取图片的头信息,不去解析真是的位图
            BitmapFactory.decodeStream(isBm,null,options);
            options.inSampleSize = calculateInSampleSize(options,requestWidth,requestHeight);
            //-------------inBitmap------------------
            options.inMutable = true;
            try{
                Bitmap inBitmap = Bitmap.createBitmap(options.outWidth, options.outHeight, Bitmap.Config.RGB_565);
                if (inBitmap != null && canUseForInBitmap(inBitmap, options)) {
                    options.inBitmap = inBitmap;
                }
            }catch (OutOfMemoryError e){
                options.inBitmap = null;
                System.gc();
            }
    
            //---------------------------------------
    
            options.inJustDecodeBounds = false;//真正的解析位图
            isBm.reset();
            Bitmap compressBitmap;
            try{
                compressBitmap =  BitmapFactory.decodeStream(isBm, null, options);//把ByteArrayInputStream数据生成图片
            }catch (OutOfMemoryError e){
                compressBitmap = null;
                System.gc();
            }
    
            return compressBitmap;
        }
    
        /**
         * 采样压缩比例
         * @param options
         * @param reqWidth 要求的宽度
         * @param reqHeight 要求的长度
         * @return
         */
        private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    
            int originalWidth = options.outWidth;
            int originalHeight = options.outHeight;
            
            int inSampleSize = 1;
    
            if (originalHeight > reqHeight || originalWidth > reqHeight){
                // 计算出实际宽高和目标宽高的比率
                final int heightRatio = Math.round((float) originalHeight / (float) reqHeight);
                final int widthRatio = Math.round((float) originalWidth / (float) reqWidth);
                // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
                // 一定都会大于等于目标的宽和高。
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    
            }
            return inSampleSize;
        }
    

    相关文章

      网友评论

          本文标题:Android Bitmap优化

          本文链接:https://www.haomeiwen.com/subject/oqxczltx.html