Android 图片压缩(防止OOM、尺寸压缩、质量压缩)
程序员文章站
2022-06-02 22:27:05
android开发中,图片的处理基本有有所接触,对于图片的压缩也有很多的博客提到,我也是查看了许多的博客后,自己总结了一下,写了一个测试的demo,我测试的图片是6720*4480 12.9m的图片...
android开发中,图片的处理基本有有所接触,对于图片的压缩也有很多的博客提到,我也是查看了许多的博客后,自己总结了一下,写了一个测试的demo,我测试的图片是6720*4480 12.9m的图片,压缩到91.24kb,下面是全部的代码,有需要改进的地方请在评论区提出,android新人还请各位大牛多多指教 !
首先在加载图片的时候要防止oom
/** * 将本地路径转化为bitmap * * @param path 本地路径 * @return 返回本地资源的bitmap */ private bitmap loadfile(string path) { file mfile = new file(path); bitmap mbitmap = null; //判读文件是否存在 if (mfile.exists()) { bitmapfactory.options moptions = new bitmapfactory.options(); //设置只加载尺寸资源 moptions.injustdecodebounds = true; //设置资源 bitmapfactory.decodefile(path, moptions); //图片加载缩方处理 coundscale(moptions); //设置加载资源模式 moptions.injustdecodebounds = false; //设置资源 mbitmap = bitmapfactory.decodefile(path, moptions); } return mbitmap; } /** * 计算缩放比例,防止oom * * @param opeions bitmapfactory.options */ private void coundscale(bitmapfactory.options opeions) { if (opeions != null) { //原图的尺寸 int orginalwidht = opeions.outwidth; int orginalhieght = opeions.outheight; //如果图片尺寸大于一定尺寸的时候进行缩放 if (orginalwidht > 1080 || orginalhieght > 1920) { //缩小倍数 int scale = 1; if (orginalwidht > orginalhieght) { //长图片的时候(以宽度为基准缩小) scale = orginalwidht / 1080; } else if (orginalwidht < orginalhieght) { //高图的时候(以高度为基准缩小) scale = orginalhieght / 1920; } else { //正方形图的时候(以宽度为基准缩小) scale = orginalwidht / 1080; } log.i(tag, "coundscale: " + scale); opeions.insamplesize = scale; } } }
统一图片的尺寸
/** * 进行图片尺寸裁剪 * * @param loadbitmap 本地图片资源 * @return 尺寸处理后的资源 */ private bitmap cutfile(bitmap loadbitmap) { bitmap mcutbitmap = null; if (loadbitmap != null) { //获取经过第一次处理后图片的尺寸; int mloadbitmapwidth = loadbitmap.getwidth(); int mloadbitmapheight = loadbitmap.getheight(); float scalex = 0; float scaley = 0; //图片的宽高比例 float picscale = (float) mloadbitmapwidth / mloadbitmapheight; //计算压缩尺寸比(无论图片大小,直接规定尺寸) if (mloadbitmapwidth > mloadbitmapheight) { //长图片的时候(宽度缩放到1080,高度安装原图的宽高比缩放尺寸) scalex = 1080.0f / mloadbitmapwidth; scaley = 1080.0f / picscale / mloadbitmapheight; } else if (mloadbitmapwidth < mloadbitmapheight) { //高图的时候 scalex = 1080.0f / mloadbitmapwidth; scaley = 1920.0f / mloadbitmapheight; } else { //正方形图的时候(按照宽度为基准缩放) scalex = 1080.0f / mloadbitmapwidth; scaley = scalex; } //创建一个矩阵 matrix mmatrix = new matrix(); //设置缩放比例 mmatrix.postscale(scalex, scaley); //生成新的bitmap mcutbitmap = bitmap.createbitmap(loadbitmap, 0, 0, mloadbitmapwidth, mloadbitmapheight, mmatrix, false); } return mcutbitmap; }
降低图片的质量
/** * 质量压缩 * * @param mbitmap 处理尺寸后的资源 * @return 压缩结束后的文件 */ private file qualtiy(bitmap mbitmap) { file mfile = null; if (mbitmap != null) { //设置压缩后图片不超过100kb int maxkb = 100; //创建一个缓存区 bytearrayoutputstream mbytearrayoutputstream = new bytearrayoutputstream(); //默认压缩质量(不压缩) int options = 100; //压缩后的大小 int endkb = 0; do { //清空缓存区 mbytearrayoutputstream.reset(); //将数据写入缓存区 mbitmap.compress(bitmap.compressformat.jpeg, options, mbytearrayoutputstream); //降低质量 options -= 5; //重新计算缓存区数据大小 endkb = mbytearrayoutputstream.tobytearray().length; //如果压缩系数小于0的时候直接跳出循环 if (options <= 0) { break; } //判断当前资源大小是否大于期望大小 } while (endkb / 1024 > maxkb); //创建一个输入流 fileoutputstream mfileoutputstream = null; bufferedoutputstream mbufferedoutputstream = null; //创建一个空文件 mfile = new file(environment.getexternalstoragedirectory().getabsolutepath() + "/manageend.jpg"); try { mfileoutputstream = new fileoutputstream(mfile); mbufferedoutputstream = new bufferedoutputstream(mfileoutputstream); //将压缩后的数据写入都空文件中 mbufferedoutputstream.write(mbytearrayoutputstream.tobytearray()); } catch (filenotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { try { if (mbytearrayoutputstream != null && mbufferedoutputstream != null && mfileoutputstream != null) { //关闭流 mbytearrayoutputstream.flush(); mbufferedoutputstream.flush(); mfileoutputstream.close(); mbufferedoutputstream.close(); mbytearrayoutputstream.close(); } } catch (ioexception e) { e.printstacktrace(); } } } return mfile; }