前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android Bitmap优化(采样压缩)

Android Bitmap优化(采样压缩)

作者头像
Zachary46
发布2021-12-08 10:27:24
1.3K0
发布2021-12-08 10:27:24
举报
文章被收录于专栏:Zachary46Zachary46

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

采样的流程:
  1. 将 BitmapFactory.Options 的 inJustDecodeBounds 参数设置为 true 并加装图片。
  2. 从 BitmapFactory.Options 中取出图片的原始宽和高,它们对应于 outWidth 和 outHeight 参数。
  3. 根据采样率的规则并结合目标 View 的所需要大小计算出采样率 inSampleSize 。
  4. 将 BitmapFactory.Options 的 inJustDecodeBounds 参数设为 false ,然后重新加装图片。
代码语言:javascript
复制
   /**
     * 采样率压缩,这个和矩阵来实现缩放有点类似,但是有一个原则是“大图小用用采样,小图大用用矩阵”。
     * 也可以先用采样来压缩图片,这样内存小了,可是图的尺寸也小。如果要是用 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;
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/11/3 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 采样的流程:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档