android图片压缩的三种方式
为了避免oom的出现,几乎每个应用都会对大图进行压缩,我现在手头做的产品就有很多地方用到,以前封装工具类的时候,都是在网上找东找西,然后拼拼凑凑,有效果就行了,一直用的迷迷糊糊,这几天工作比较闲,正好系统的总结梳理一下图片压缩方式:
图片压缩现在常见的有三种方式:
1、等比压缩,等比压缩是保持原图长宽比例的压缩,只是图片变小,展示的还是原图的所有内容(区别于第二种通过Matrix压缩,可以选取图片的一部分,类似于上传头像时,让你在图上选一块zoom的形式)。等比压缩用的的主要是BitmapFactory.Options,通过options缩放比例的设置,来生成缩略图:
/** * @param path 图片路径 * @param targetSize 缩放后期待的长边(图片长和宽大的那一个边)的长度 * @param targetW 期待的缩放后宽度 * @param targetH 期待的缩放后高度 * @return */ public static Bitmap equalRatioScale(String path,int targetW,int targetH){ // 获取option BitmapFactory.Options options = new BitmapFactory.Options(); // inJustDecodeBounds设置为true,这样使用该option decode出来的Bitmap是null, // 只是把长宽存放到option中 options.inJustDecodeBounds = true; // 此时bitmap为null Bitmap bitmap = BitmapFactory.decodeFile(path, options); int inSampleSize = 1; // 1是不缩放 // 计算宽高缩放比例 int inSampleSizeW = options.outWidth / targetW; int inSampleSizeH = options.outHeight / targetH; // 最终取大的那个为缩放比例,这样才能适配,例如宽缩放3倍才能适配屏幕,而 // 高不缩放就可以,那样的话如果按高缩放,宽在屏幕内就显示不下了 if (inSampleSizeW > inSampleSizeH) { inSampleSize = inSampleSizeW; }else { inSampleSize = inSampleSizeH; } // 设置缩放比例 options.inSampleSize = inSampleSize; // 一定要记得将inJustDecodeBounds设为false,否则Bitmap为null options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(path, options); return bitmap; }
2、通过Matrix进行更加灵活的缩放:这种方式主要是通过构建缩放矩阵和Bitmap.createBitmap方法来实现灵活缩放,宽和高缩放的比例可以不一致,而且通过Bitmap.createBitmap方法创建出来的是新的位图,这个位图可以是选取原图的一部分,而不是对原图进行整体缩放!类似于上传头像时,让你在原图上扣下来一块的效果,控制非常灵活。
/** * @param path 原图路径 * @param offsetX 截取开始点在X轴偏移量 * @param offsetY 截取开始点在Y轴偏移量 * @param targetW 截取多宽(像素) * @param targetH 截取多高(像素) * @return */ public static Bitmap matrixScale(String path,int offsetX,int offsetY,int targetW,int targetH){ // 构建原始位图 Bitmap bitmap = BitmapFactory.decodeFile(path); // 获取原始宽高 int width = bitmap.getWidth(); int height = bitmap.getHeight(); // 计算宽高缩放比例,targetW,targetH即期待缩放完成后位图的宽高 float scaleW = (float)targetW / width; float scaleH = (float)targetH / height; // 将缩放比例放进矩阵 Matrix matrix = new Matrix(); matrix.postScale(scaleW, scaleH); // 这个方法作用非常多,详细解释一下各个参数的意义! // bitmap:原始位图 // 第二到第五个参数,即截取原图哪一部分构建新位图, // offsetX和offsetY代表在X轴和Y轴上的像素偏移量,即从哪个位置开始截取 // width和height代表截取多少个像素,但是要注意,offsetX+width应该小于等于原图的宽度 // offsetY+height小于等于原图高度,要不然会报错,因为截到原图外面去了 // 像下面这样填写,就代表截取整个原图, // Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false); // 如果填写100,100,200,200,就代表 // 从原图左上角往右和下各偏移100像素,然后往后和往下各截取200构建新位图 // matrix:缩放矩阵 // 最后一个参数表示如果矩阵里面还存放了过滤条件,是否按条件过滤(如果matrix里面只放了平移数据),最后一个参数设置成什么都不会生效 bitmap = Bitmap.createBitmap(bitmap, offsetX, offsetY, width, height, matrix, false); return bitmap; }
3、无损压缩,无损压缩是说图片大小和清晰度看上去和原图没有什么差别,但是确实size缩小了,这里缩小的原理是牺牲了分辨率等其他直观看不到的东西,看起来和原图一样,但是一放大就立马失真了,不会和原图一样放大很多才会逐渐变得不清晰。无损压缩后的图片像素并不会减少,而Bitmap占用内存的定义就是像素点占的内存,所以以Bitmap的方式加载到内存中时,和压缩前占用的内存是同样大的,原来会oom的图片,质量压缩后同样会oom;但是,质量压缩后将流输出到文件中,文件的size会大幅度减小,所以质量压缩特别适合在Android端进行图片上传的时候进行图片压缩,既能保持上传后的清晰度,又能减小size。另外质量压缩不是可以无限缩小的,降低到一定程度,就算把quality设置的再小,size也不会再降低了。另外这种方式最好返回保存压缩后的图片保存的文件路径,而不要直接返回Bitmap,示例就懒得改了。
<pre name="code" class="java">/** * @param path 图片路径 * @param quality 质量 0-100,100表示原图 * @return */ public static Bitmap losslessScale(String path,int quality){ Bitmap bitmap = BitmapFactory.decodeFile(path); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.JPEG, quality, baos); Log.e("哈哈","原始大小:" + baos.toByteArray().length); // 因为质量压缩不是可以无限缩小的,所以一张高质量的图片,再怎么压缩, // 最终size可能还是大于你指定的size,造成异常 // 所以不建议循环压缩,而是指定quality,进行一次压缩就可以了
// while (baos.toByteArray().length / 1024 > maxSize) {
// quality -= 10;
// baos.reset();
// bitmap.compress(CompressFormat.JPEG, quality, baos);
// Log.e("哈哈","过程中大小为:"
// + baos.toByteArray().length);
// } bitmap.compress(CompressFormat.JPEG, quality, baos); Log.e("哈哈","最终大小" + baos.toByteArray().length); Bitmap compressedBitmap = BitmapFactory.decodeByteArray( baos.toByteArray(), 0, baos.toByteArray().length); return compressedBitmap; }
一张图片处理过程,建议先进行等比压缩或者Matrix压缩后,再进行质量压缩,这样组合使用,不管是生成缩略图还是图片上传,效果都不错
android图片压缩的三种方式相关推荐
- 对于图片压缩的 三种方式
android 图片压缩方法: 第一:质量压缩法: 复制代码 代码如下: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStr ...
- 实现精灵图片绝对定位的三种方式(伪)
精灵图片绝对定位的三种方式(伪) 有强迫症的我为此困扰了一上午,说白了还是自己实力不够,想法总被局限. 实现结果如上图中间的为最终满意样品 整体用列表写的` 左1: 把整体看成一个背景图加上面文字: ...
- Android录制音频的三种方式
对于录制音频,Android系统就都自带了一个小小的应用,可是使用起来可能不是特别的灵活.所以有提供了另外的俩种. 下边来介绍下这三种录制的方式; 1.通过Intent调用系统的录音器功能,然后在录制 ...
- Android 音频录制 的三种方式
对于录制音频,Android系统就都自带了一个小小的应用,可是使用起来可能不是特别的灵活.所以有提供了另外的俩种. 下边来介绍下这三种录制的方式; 1.通过Intent调用系统的录音器功能,然后在录制 ...
- Android 使用OpenCV的三种方式(Android Studio)
from: http://blog.csdn.net/sbsujjbcy/article/details/49520791 其实最早接触OpenCV是很久很久之前的事了,大概在2013年的5,6月份, ...
- android xml解析的三种方式
2019独角兽企业重金招聘Python工程师标准>>> 在android开发中,经常用到去解析xml文件,常见的解析xml的方式有一下三种:SAX.Pull.Dom解析方式.最近做了 ...
- Android解析XML的三种方式
在Android中提供了三种解析XML的方式:DOM(Document Objrect Model),SAX(Simple API XML),以及Android推荐的Pull解析方式. 如图: 本篇博 ...
- Android实现加载(loading)图片旋转的三种方式
我们在Android应用开发中可能经常用到类似如下效果的加载过程中的图片旋转效果: 上面的图片是一张gif格式的动态图片,我们知道,在Android中对gif动态图片的支持是不好的.可以通过第三方ja ...
- 转载.Android HAL实现的三种方式(1) - 基于JNI的简单HAL设计
现在在Android上的HAL开发总的来说还是随意性比较大,Android也并没有规范好一个具体的框架,下面我将根据Jollen的Mokoid工程,自己做了一些改动,分别给大家介绍一下三种实现方式. ...
最新文章
- [HTTP]Etag的工作流程
- C语言工程实践-简单文本编辑器
- C++接口工程实践:有哪些实现方法?
- 牛客练习赛89--牛牛防疫情
- PWA(Progressive Web App)入门系列:Push
- BZOJ2948 : [Poi2001]绿色游戏
- 【译】UI设计基础(UI Design Basics)--启动与停止(Starting and Stopping)(五)
- 在.Net中读写config文件的各种方法
- 全国各地收货详细地址_2020高考成绩在哪里查询 2020全国各地高考分数查询时间地址最新...
- 640x360,H264 SPS头如何表示高度?
- 教你用go freetype根据用户昵称生成头像
- windows环境搭建redis集群
- MATLAB图像处理(一)——计算机图形学之图像形状识别
- R语言——相关系数图
- [论文写作笔记] C2论文写作结构与思路 C6 让研究方法称为加分项
- win10自带计算机应用恢复,win10重置电脑后怎么恢复应用_win10重置后恢复软件的方法...
- 10大协作办公工具:实现团队工作效率最大化
- 基于C#制作一个ChatGPT桌面助手
- 美颜sdk动态贴纸是什么?
- NOIP2016 “西湖边超萌小松鼠” 模拟赛
热门文章
- 20X20 FCPX插件数字信息化故障干扰像素损坏风格英文标题模板GlitchAnimatedTypeface
- 基于RealSense的坐姿检测技术
- c语言中文定义什么类型,typedef在c语言中是什么意思?
- http://dev.firnow.com/course/3_program/java/javashl/200726/11199.html
- 华为Cloud Native Lives课程第一课-云原生技术的前世今生
- 【 bzoj 4355 】 Play with sequence - 线段树乱搞
- 摩羯男喜欢你的一些表现
- Python爬虫项目分享二:《爬取周杰伦的歌曲评论》
- 阿龙的学习笔记---python相关杂七杂八的记录
- 台式计算机开始不显示,台式机连接投影仪不显示怎么办