图片过大引起的OOM,ImageView无法显示问题

本文探讨了使用bitmap.compress()进行图片压缩时遇到的内存溢出问题,并提出了一种新的压缩方法,通过调整BitmapFactory.Options参数实现图片尺寸的有效控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近处理图片遇到一些问题,网上的图片压缩很多都是使用bitmap.compress(),但是发现还是有OOM

原先的代码,有问题的:

public String cutPictureQuality(Bitmap bitmap, String fname) {

        String fileName = fname + ".jpg";// UUID.randomUUID().toString().replace("-","") + ".jpg";
        String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + context.getPackageName() + "/UserIcon";
        //Environment.getExternalStorageDirectory() + File.separator + savePackage;

        // 判断文件夹存在
        File file = new File(filePath);
        if (file != null && !file.exists()) {
            file.mkdirs();
        }

        try {

            // 第一次压缩
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

            FileOutputStream fos = new FileOutputStream(new File(filePath, fileName));

            int options = 100;
            // 如果大于150kb则再次压缩,最多压缩三次
            while (baos.toByteArray().length / 1024 > 150 && options != 10) {
                // 清空baos
                baos.reset();
                // 这里压缩options%,把压缩后的数据存放到baos中
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
                options -= 30;
            }
            fos.write(baos.toByteArray());
            fos.close();
            baos.close();

        } catch (Exception e) {
        }
        return filePath + File.separator + fileName;
    }

以上使用compress压缩,得到的结果加载时还是会发生oom,网上找了资料说compress压缩的是图片保存到内存的大小,

加载的时候,获取的图片大小还是不变的

现在采用的压缩方式是

 public Bitmap cutPictureSize(String filePath, int reqWidth, int reqHeight) {

        Display mDisplay = ((Activity) context).getWindowManager().getDefaultDisplay();
//        int width = mDisplay.getWidth();
//        int height = mDisplay.getHeight();

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//只是获取图片边框,不加载图片
        BitmapFactory.decodeFile(filePath, options);
        options.inSampleSize = 4;//设置采样比例 这里是四行取一行,4列取1列,得到的大小是原来的1/16
        options.inJustDecodeBounds = false;  //然后设置加载图片
        return BitmapFactory.decodeFile(filePath, options);
    }

加载的思路基本是这样,也可以根据图片的width和height来计算inSamplesize

 private int cutBySize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        return inSampleSize;
    }

基本就是这样,因为刚开始没有了解过Glide等第三方图片加载框架,所以遇到很多坑。后面的项目会采用第三方加载,有同样问题的可以去了解下


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值