对于安卓开发来说,内存溢出(oom)是安卓程序员不可绕过的坎,特别是对于大图片来说,加载时候的大内存更是常常让人胆战心惊。

很多安卓程序员都知道,避免图片加载大内存的最常用方法,那就是用BitmapFactory的options,设置这个options的inSampleSize来达到将图片按照实际显示大小去缩小自己图片,来达到减少内存。

若是你去百度inSampleSize,那么你会看到最多的用法是这样的:

private Bitmap getimage(String srcPath) {BitmapFactory.Options newOpts = new BitmapFactory.Options();//开始读入图片,此时把options.inJustDecodeBounds 设回true了newOpts.inJustDecodeBounds = true;Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空newOpts.inJustDecodeBounds = false;int w = newOpts.outWidth;int h = newOpts.outHeight;//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为float hh = 800f;//这里设置高度为800ffloat ww = 480f;//这里设置宽度为480f//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可int be = 1;//be=1表示不缩放if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放be = (int) (newOpts.outWidth / ww);} else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放be = (int) (newOpts.outHeight / hh);}if (be <= 0)be = 1;newOpts.inSampleSize = be;//设置缩放比例//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了bitmap = BitmapFactory.decodeFile(srcPath, newOpts);return compressImage(bitmap);//压缩好比例大小后再进行质量压缩}

看起来好像完全没有问题,根据自己想要的的图片大小,然后去计算将原图缩放的inSampleSize,然后赋值给bitmap以达到缩放图片大小。

很多人看到这样算法便喜不自胜急忙将它复制到自己工程,可是复制进去之后他们却傻眼了,内存跟以前没用时候差不多啊。

为什么会这样?

因为,inSampleSize只能为整数啊。

我们举个例子,假如有一张高度为700的图片,你想把它缩放为500,你要是用上面那个算法去算,你会发现,你算出来的inSampleSize其实为1!!!

而1,那就是图片不变,没有压缩

在这里说一下,inSampleSize的值只能为2的倍数,1,4,8,16……

1的话是不变,2的话是图片变为原来4分之一大小,8是变为原来64分之一大小,以此类推

所以到了最后,你会发现你想要压缩的图片其实根本没有被压缩。

好吧,就算有变,但其实也很难,甚至几乎不可能变到你想要的图片大小,就比如上面说的那个例子,无论你设置inSampleSize为什么值,你都会发现,你最终得到的图片要么太大要么太小。

但是安卓怎么可能那么垃圾,

对的,安卓才不会这么垃圾呢,

其实与inSampleSize相关的还有几个参数,比如inScaled,inTargetDensity,inDensity。

这些参数其实非常有用,与inSampleSize一起用才会完美。

其中:

inScaled:将它设置为true,那么代表这张图片可以缩放

inDensity:图片的原来密度,默认一般为160.

inTargetDensity:图片的目标密度,图片操作之后的密度

其实你设置一张图片的BitmapFactory的options,这张图片的输出宽高是这样决定的:

输出图片的宽高= (原图片的宽高 * (inTargetDensity / inDensity)) / inSampleSize

所以你要是现将一张700的图片缩小为600,你可以计算一下图片的inTargetDensity,如下面方法

 /*** 获取特定大小缩略图* @param imageid 图片资源id* @param size 你想要获取的图片大小尺寸* @return*/public Bitmap getSampleBitmap2(int imageid,int size){BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds=true;BitmapFactory.decodeResource(getResources(),imageid,options);options.inPreferredConfig = Bitmap.Config.ARGB_8888;options.inSampleSize= calculateInSampleSize(options,size);//设置图片可以缩小options.inScaled = true;int calsize=options.outHeight>options.outWidth?options.outWidth:options.outHeight;/*** 计算图片缩小的目标密度,在这里说一下,有一条公式:* 输出图片的宽高= (原图片的宽高 * (inTargetDensity / inDensity)) / inSampleSize* 一般来说,图片的options.inDensity默认为160* 所以inTargetDensity计算公式为:(希望输出的宽高*options.inDensity)/(原来图片的宽高/options.inSampleSize)*/options.inTargetDensity =(size*options.inDensity)/(calsize/options.inSampleSize);options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeResource(getResources(),imageid,options);return bitmap;}
 //谷歌源码里面的计算simplesize方法,public int calculateInSampleSize(BitmapFactory.Options options,int size) {int reqWidth,reqHeight;// Raw height and width of imagefinal int height = options.outHeight;final int width = options.outWidth;if(options.outHeight>options.outWidth){reqWidth=size;reqHeight=size*options.outHeight/options.outWidth;}else{reqWidth=size*options.outWidth/options.outHeight;reqHeight=size;}int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {final int halfHeight = height / 2;final int halfWidth = width / 2;// Calculate the largest inSampleSize value that is a power of 2 and// keeps both// height and width larger than the requested height and width.while ((halfHeight / inSampleSize) > reqHeight&& (halfWidth / inSampleSize) > reqWidth) {inSampleSize *= 2;}}return inSampleSize;}

比如我将一张宽700图片缩小为宽450的图片,在没设置inTargetDensity的时候

计算出来的inSampleSize为1,图片尺寸很大,没有变

所占用内存:

差不多40M

而在设置了inTargetDensity 之后

计算出来的inSampleSize仍然为1,但是图片尺寸却变为我想要获取的大小450了!!!

而所占用的内存:

只有14M左右!!!!!!!!!!

40?14!是不是感觉世界瞬间美好很多啦~

对了,后面顺便说一下,若你将根据这个方法得到的图片赋值给另一个bitmap的时候,可能会出现,这个被赋值的bitmap图片虽然图片大小不变,但是显示变了,那是因为这个inTargetDensity 属性不会自动赋值给新的bitmap,可以这样做

//创建一张新的bitmap,跟传入图片一样宽的正方形bitmap,Bitmap b=Bitmap.createBitmap(bitmapSize,bitmapSize, Bitmap.Config.ARGB_8888);//将图片密度修改为上面那张的图片密度b.setDensity(bitmap.getDensity());

这样新得到的b图片就会跟原来那张一样了

如何获取一张特定大小的压缩图片相关推荐

  1. JS中通过指定大小来压缩图片

    前不久王二写了一个图片处理库,可以指定图片质量压缩图片,调用的是javaScript的原生方法 toDataURL 和 toBlob,库里有如下这些方法: 但是通过质量压缩图片有一些不足之处:无法确定 ...

  2. 上传图片到OSS,并按指定大小范围压缩图片。完整工具类+三层调用

    使用阿里的Oss服务器,做图片服务器. 项目功能为,前端,调用后端的接口,上传用户的图片! 1.controller类 @RestController @RequestMapping("/o ...

  3. 如何将图片压缩到指定大小?压缩图片大小的方法

    很多报名平台都对图片大小有固定的数值要求,所以不少小伙伴来问,怎么压缩图片200k以下(图片压缩到指定大小 图片压缩大小至指定kb以下-压缩图)?想要把图片压缩指定大小就要用到一些比较专业的工具,今天 ...

  4. 如何修改、缩小截图图片大小,压缩图片。

    一. 我们在使用截图工具截比较大图的时候,发现图片内存大小太大,不方便上传到后台使用.如何压缩截图的图片大小? 无论是使用Windows自带还是qq或者其他的截图工具,图片大小会根据你的截图范围大小而 ...

  5. java采用降低图片分辨率大小来压缩图片大小

    我看了网上大多数对图片的压缩都是基于对图片width和hight进行裁剪来降低图片实际大小,但这种方式容易导致图片内容的丢失,所以推荐大家采用以下这种方式 import java.awt.image. ...

  6. 图片压缩大小java_压缩图片大小(Java源码)

    /** * * 直接指定压缩后的宽高: * @param oldFile * 要进行压缩的文件 * @param width * 压缩后的宽度 * @param height * 压缩后的高度 * @ ...

  7. 【Python黑科技】图片太大不能上传?三种压缩图片大小的方法(代码注释详细)

    目录 实现效果 原图大小8.46MB PIL库quality降低图片质量方式压缩图片366KB PIL库thumbnail压缩图片大小来压缩图片985KB OpenCV缩放图片大小来压缩图片 177K ...

  8. 压缩pdf文件到特定大小,pdf格式文件如何压缩到最小

    压缩pdf文件到特定大小?pdf是日常办公中比较常见的一种文件格式,但是有时候pdf文件的容量会比较大,上传到某些平台会有限制,那么p我们就需要压缩pdf文件,但是有时候压缩处理会模糊,今天我给大家介 ...

  9. 如何获取JPEG图片质量和预测压缩图片大小

    前言 发起这个博客的原因是近期有个需求,当用户在APP中发送图片时,APP要显示将图片压缩到指定尺寸的选项,选项中要显示压缩后图片的大小(占空间),出发点是为了控制上传流量.那转换成技术问题实际上就是 ...

最新文章

  1. 拍个自拍,让Python告诉你,军训过后你黑了几度?
  2. Adb+.net 实现微信跳一跳自动化
  3. 谷歌五笔输入法电脑版_“五笔输入法”打字速度更快,为什么却没啥人用?
  4. 成为最大的独立开源公司,对SUSE意味着什么? | 人物志
  5. 《Pro ASP.NET MVC 3 Framework》学习笔记之二十四【Controllers和Actions】
  6. 你想过没有,学校从来没教过你怎么赚钱
  7. react build后直接从浏览器打开
  8. javascript中的弹框
  9. 数据分析师23-京东商业数据分析有感
  10. [修練營ASP.NET]淺談多層式架構 (Multi Tiers)
  11. 5-6 uniapp 图片压缩
  12. Yarn访问8088端口时提示 Can not find any active RM. Will retry in next 12 seconds.
  13. 临界资源的同步与互斥,区分临界资源与临界区,二义性分析
  14. 上海东方广播电台 动感101.7(FM101.7)在线收听
  15. Karatsuba-Ofman乘法器
  16. IDEA开发中包(package)的作用
  17. ibaits中进行log4j控制台输出
  18. Docker强制删除镜像
  19. 手机中必有的4款APP神器,你可以不全有,但至少会有一个
  20. python 3.7 最佳python中文工具书籍下载

热门文章

  1. 第二话、转行自学到入行程序员圈子
  2. 学C/C++开发,学历到底重不重要?
  3. 使用IDEA 刷新项目 清除缓存
  4. python url中文乱码
  5. 找不到客户采购邮箱?其实你只需要精通谷歌搜索
  6. 李航统计学习方法EM算法三枚硬币例子Q函数推导
  7. 2021计算机四级网络,2021年9月全国计算机等级考试《网络工程师(四级)》题库(在线考试)标准班...
  8. 【2022最新Java面试宝典】—— Tomcat面试题(15道含答案)
  9. 撤销前进快捷键_撤销与回复的快捷键
  10. (转)使用XML、XSLT和XPath创建可排序、分页、重用的数据显示页