android 图片按照尺寸来压缩
奔跑的男人 · 500浏览 · 发布于2019-07-24
做了一个项目,CPU比较低端,用户会时不时上传一些4K得图片来展示,加载速度就不用说了,CPU发热叶比较严重,就写了这个压缩得工具类,算是做一个笔记吧,
在展示图片之前,先压缩图片,压缩得规律是
1:小于屏幕得宽高得图片直接跳过,不压缩
2:大于屏幕的尺寸的,按照3/4的比例压缩,循环压缩,直到图片尺寸小于屏幕,对机器好一点,
代码比较简单,看看就知道了。里面部分代码在使用的时候需要改动,这是从项目里面copy出来的
调用方法
private void compressPic() { String path = "/sdcard/01.jpg"; CompressImageUtil comPressUtil = new CompressImageUtil(TestCompressActivity.this); comPressUtil.compressPic(path, new CompressImageListener() { @Override public void backErrorDesc(String desc) { MyLog.cdl("======压缩失败==" + desc); } @Override public void backImageSuccess(String oldPath, String imagePath) { Bitmap map = BitmapFactory.decodeFile(imagePath); mainImageNew.setImageBitmap(map); } }); }
工具类 SharedParManager。getWidth(); 表示获取屏幕的宽度,这个在使用中需要自行修改
package com.etv.util.image; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import com.etv.http.util.CompressImageRunnable; import com.etv.listener.CompressImageListener; import com.etv.service.EtvService; import com.etv.util.MyLog; import com.etv.util.SharedPerManager; import java.io.File; public class CompressImageUtil { Context context; public CompressImageUtil(Context context) { this.context = context; } public void compressPic(String path, CompressImageListener listener) { try { MyLog.cdl("=========准备解压图片===" + path); File file = new File(path); if (!file.exists()) { listener.backErrorDesc("检测文件不存在"); return; } float width = SharedPerManager.getScreenWidth(); float height = SharedPerManager.getScreenHeight(); Bitmap mapChange = BitmapFactory.decodeFile(path); float imageWidth = mapChange.getWidth(); float imageHeight = mapChange.getHeight(); if (imageWidth < width && imageHeight < height) { //不需要转码直接返回 listener.backImageSuccess(null, path); return; } while (imageWidth > width || imageHeight > height) { imageWidth = imageWidth * 3 / 4; imageHeight = imageHeight * 3 / 4; } MyLog.cdl("===图片压缩的尺寸===" + imageWidth + " / " + imageHeight); CompressImageRunnable runnable = new CompressImageRunnable(file, imageWidth, imageHeight, listener); EtvService.getInstance().executor(runnable); } catch (Exception e) { e.printStackTrace(); } } }
压缩是放在线程里面执行的,里面最后一句话是在线程池里面的,因为我使用的场景是批量中使用的.可以直接new Thread使用.
package com.etv.http.util; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import com.etv.listener.CompressImageListener; import com.etv.util.MyLog; import com.etv.util.image.ImageUtil; import java.io.File; import java.io.FileOutputStream; public class CompressImageRunnable implements Runnable { File fileCompress; CompressImageListener listener; float width; float height; public CompressImageRunnable(File fileCompress, float width, float height, CompressImageListener listener) { this.fileCompress = fileCompress; this.listener = listener; this.width = width; this.height = height; } @Override public void run() { compressImage(); } public void compressImage() { String imagePath = fileCompress.getPath(); String basePath = imagePath.substring(0, imagePath.lastIndexOf("/") + 1); String fileName = fileCompress.getName(); Bitmap bitmap = bitmapFactory(imagePath); if (bitmap == null) { backFailed("解析图片失败"); return; } String nameCache = fileName.substring(0, fileName.indexOf(".")) + "_compress.jpg"; String newPath = basePath + nameCache; boolean isSave = saveBitmapToSdcard(newPath, bitmap); if (!isSave) { return; } backSuccess(newPath); } /** * 保存方法 */ public boolean saveBitmapToSdcard(String path, Bitmap bitmap) { try { File f = new File(path); if (f.exists()) { f.delete(); } f.createNewFile(); FileOutputStream out = new FileOutputStream(f); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); out.flush(); out.close(); return true; } catch (Exception e) { String messageError = e.toString(); backFailed(messageError); e.printStackTrace(); } return false; } /** * 压缩图片使用,采用BitmapFactory.decodeFile。这里是尺寸压缩 */ private Bitmap bitmapFactory(String imagePath) { Bitmap bm = null; try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; //获取当前图片的边界大小,而不是将整张图片载入在内存中,避免内存溢出 BitmapFactory.decodeFile(imagePath, options); options.inJustDecodeBounds = false; options.inSampleSize = ImageUtil.caculateSampleSize(options, width, height); bm = BitmapFactory.decodeFile(imagePath, options); // 解码文件 } catch (Exception e) { listener.backErrorDesc(e.toString()); e.printStackTrace(); } return bm; } private void backSuccess(final String imagePath) { try { if (listener == null) { return; } handler.post(new Runnable() { @Override public void run() { String oldPath = fileCompress.getPath(); listener.backImageSuccess(oldPath, imagePath); } }); } catch (Exception e) { e.printStackTrace(); } } private Handler handler = new Handler(); private void backFailed(final String desc) { try { if (listener == null) { return; } handler.post(new Runnable() { @Override public void run() { } }); listener.backErrorDesc(desc); } catch (Exception e) { e.printStackTrace(); } } }
相关推荐
android下vulkan与opengles纹理互通
talkchan · 1173浏览 · 2020-11-23 10:37:39
Android 使用RecyclerView实现轮播图
奔跑的男人 · 2171浏览 · 2019-05-09 17:11:13
微软发布新命令行工具 Windows Terminal
吴振华 · 866浏览 · 2019-05-09 17:15:04
在华为写了十几年代码,我为什么还没有被拿去“祭天”
追忆似水年华 · 1198浏览 · 2019-05-09 17:22:20
android 通过修改图片像素实现CircleImageView
吴振华 · 1125浏览 · 2019-05-09 22:26:56
分类专栏
最新发布
最热排行
0评论