热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

压缩指定大小的BitMap

序言在开发中,我们常常会遇到构造图片,加载显示图片的情况。我们可以使用BitMapFactory的decodexxx方法来构造BitMap对象。但现在普遍照片的质量,像素都很高,如果直接把

序言

在开发中,我们常常会遇到构造图片,加载显示图片的情况。我们可以使用BitMapFactory的decode xxx 方法来构造BitMap对象。但现在普遍照片的质量,像素都很高,如果直接把照片拿来使用,加载到内存,就会很容易造成内存泄漏。也有浪费的嫌疑,比如我程序中只需要,200*200的图像,却是用2048x1536的图加载进去,这就不很浪费,很没有必要么,下面就将说明,如何对BitMap进行压缩处理,得到想要的尺寸的图片。

未处理的图片大小

我们想来看一下没有经过压缩处理的图片的大小。

Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
//默认的图片格式是Bitmap.Config.ARGB_8888
Log.e(TAG, "onActivityResult: 图片的宽:" + bitmap.getWidth() + "--图片的高:"
+ bitmap.getHeight() + "--图片大小:" + bitmap.getWidth() * bitmap.getHeight() * 4 / 1024 / 1024 + "M");

这里默认是图片格式是ARGB_8888所以一个像素是占32位,8位等于1个字节,所以一个像素占4个字节内存。此时输出的log信息是:

E/MainActivity: onActivityResult: 图片的宽:1680--图片的高:1050--图片大小:6M

压缩处理成指定大小的图片

代码如下:

BitmapFactory.Options optiOns= new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);
Log.e(TAG, "onActivityResult: 压缩之前图片的宽:" + options.outWidth + "--压缩之前图片的高:"
+ options.outHeight + "--压缩之前图片大小:" + options.outWidth * options.outHeight * 4 / 1024 / 1024 + "M");

options.inSampleSize = calculateInSampleSize(options, 200, 200);
Log.e(TAG, "onActivityResult: inSampleSize:"+ options.inSampleSize);
options.inJustDecodeBounds = false;
Bitmap afterCompressBm = BitmapFactory.decodeFile(imagePath, options);
//默认的图片格式是Bitmap.Config.ARGB_8888
Log.e(TAG, "onActivityResult: 图片的宽:" + afterCompressBm.getWidth() + "--图片的高:"
+ afterCompressBm.getHeight() + "--图片大小:" + afterCompressBm.getWidth() * afterCompressBm.getHeight() * 4 / 1024 / 1024 + "M");

private int calculateInSampleSize(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 halfHeight = height / 2;
final int halfWidth = width / 2;

while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}

return inSampleSize;
}

log输出结果如下:

E/MainActivity: onActivityResult: 压缩之前图片的宽:1680--压缩之前图片的高:1050--压缩之前图片大小:6M
E/MainActivity: onActivityResult: inSampleSize:4
E/MainActivity: onActivityResult: 图片的宽:420--图片的高:263--图片大小:0M

我们看到图片的大小就变得很小了,这样就不会占很大的内存导致内存泄漏问题。这里我们可以着重看一下calculateInSampleSize这个方法的逻辑。内部代码逻辑不难,就是通过我们传入的想要的图片宽高值来计算inSampleSize的大小。这里我们通过log发现输出的inSampleSize值为4。此刻就表示,图片的宽变为原来的四分之一,高变为原来的四分之一。整张照片的像素就变为原来的16分之一。这样就达到了压缩的效果。

显示效果对比

压缩前,原图:

压缩前(图片进行过裁剪,图片大小可能有些许误差)

压缩后,图片:

压缩后(图片进行过裁剪,图片大小可能有些许误差)

补充

这里默认的图片格式是Bitmap.Config.ARGB_8888,我们也可以改变图片格式来对图片进行减小。这里补充下各种格式对应的字节大小:
- ARGB_8888 ->一个像素点占32位->4个字节
- RGB_565 ->一个像素点占16位->2个字节
- ARGB_4444 ->占16位->2个字节
- RGBA_F16 ->64位->8个字节
- ALPHA_8 ->不存储颜色信息,只存储透明度->一个像素占1个字节


推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Android Bitmap 缓存策略
    Android中最常用到缓存的地方就是图片,通过过缓存即可以提高应用程序的效率,又可以节省用户的流量。图片的缓存简单来说可以分为SD卡缓存和内存缓存,也可以俩者配合使用。Andr ... [详细]
  • 要点:假如有10亿元素,全部数据读进内存,占用1000000000*4102410241024≈3.725G,爆炸!解决方法:bitmap算法,每一位都能 ... [详细]
  • 网上有很多解决android加载bitmap内存溢出的方法,搜了一圈做下整理总结。项目里需求是拍摄多图之后上传,部分手机会内存溢出。常用一种解决方法:即将载入的图片缩小,这种方式以牺牲图片的质量为代价 ... [详细]
  • BitMap的原理和实现方法
    这篇文章主要介绍“BitMap的原理和实现方法”,在日常操作中,相信很多人在BitMap的原理和实现方法问题上存在疑惑,小编查阅了各式资料,整理出简 ... [详细]
  • Android中Bitmap与Drawable的区别有哪些?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
author-avatar
leooooo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有