博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android中图片优化之webp使用
阅读量:6988 次
发布时间:2019-06-27

本文共 3131 字,大约阅读时间需要 10 分钟。

博客出自:,转载注明出处! All Rights Reserved !

有关图片的优化,通常我们会用到LruCache(使用强引用、强制回收的办法),会用到SoftReference(使用url做key,bitmap做value的方法),会用到根据手机屏幕来缩放图片,会及时回收图片所占用的内存等方法,但说实在的,这些方法治标不治本,图片该多大还多大,从软件上我们基本上能做到处理图片的极限,那么只剩下考虑从硬件来上优化图片,这就讲到了今天所要说的webp。

其中webp不仅仅能应用在Android上,同样IOS和web端也同样可以使用。

有关webp的简介,腾讯同学有详细介绍,我不再多说。

常用的webp转换工具有:,,

一张279k的png图片可以转换成67.5k的webp图片,而且不失真

第一步添加webp支持,添加so包和lib包

第二步,添加WebpUtils文件,里面有通过so包来处理webp文件成为byte数组的方法

第三步,应用

效果图:

你最想要的源码!

附安卓SDK文档给出的官方压缩图片算法:

public static Bitmap getBitmapBySize(String path, int width, int height) {		BitmapFactory.Options option = new BitmapFactory.Options();		option.inJustDecodeBounds = true;		BitmapFactory.decodeFile(path, option);		option.inSampleSize = computeSampleSize(option, -1, width * height);		option.inJustDecodeBounds = false;		Bitmap bitmap = null;		try {			bitmap = BitmapFactory.decodeFile(path, option);		} catch (Exception e) {			e.printStackTrace();		}		return bitmap;	}	public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {		int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);		int roundedSize;		if (initialSize <= 8) {			roundedSize = 1;			while (roundedSize < initialSize) {				roundedSize <<= 1;			}		} else {			roundedSize = (initialSize + 7) / 8 * 8;		}		return roundedSize;	}	private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {		double w = options.outWidth;		double h = options.outHeight;		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));		if (upperBound < lowerBound) {			// return the larger one when there is no overlapping zone.			return lowerBound;		}		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {			return 1;		} else if (minSideLength == -1) {			return lowerBound;		} else {			return upperBound;		}	}

算法的意思是:将原图压缩为大概width*height个像素,原图像素数/(width*height)=压缩比率^2,得到这个比率后,对原图进行等比例压缩;避免的误区是,以为放入的width*height就是要压缩到的大小

压缩像素为1280*720,保证清晰度同比压缩到,如果超过则取更小值,因此文件大小不能确定,测试两组数据如下:

原图长宽     大小   压缩后长宽      压缩后大小       长宽比   大小比      inSampleSize

3120*4160 3.41m 612*816 465kb(理论140)  25.99          7.5        5

2448*3264 1.43m 780*1040 265kb(理论160)  9.85            5.53      3

2448*3264 1.8m 612*816 294kb(理论115) 16    6.27      4

图片大小理论值都比实际值要小,可见图片长宽与大小不成正比;第三组数据和第一组数据共用一台手机,可见同一手机压缩后的长宽比是一致的。图片大小压缩大小最小为5倍;而一般情况下图片解析得到的Bitmap大小会比文件大5倍左右。

另外页面中重新定义的ImageView,如果使用当前页面的context作为引入,则当页面关闭后可能会引起内存泄露,同时会引起OOM,引用链过长同时未被释放;方法是将Application作为context加入ImageView,在页面destroy时,清除context,以及View

public static void unbindDrawables(View view) {        if (view.getBackground() != null) {            view.getBackground().setCallback(null);        }        if (view instanceof ViewGroup) {            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {                unbindDrawables(((ViewGroup) view).getChildAt(i));            }            ((ViewGroup) view).removeAllViews();        }    }

借这个机会讲讲避免内存泄露的方法:

Cursor用后及时关闭,Bitmap及对象及时回收,避免在循环体中new对象,注册的广播等监听及时取消,尽量使用Application而非context。

其他内存优化的方法:
你可能感兴趣的文章
Viewstate
查看>>
ASP.NET MVC之Unobtrusive Ajax(五)
查看>>
[LeetCode] Dungeon Game 地牢游戏
查看>>
实现一个 能在O(1)时间复杂度 完成 Push、Pop、Min操作的 栈
查看>>
Java 序列化的高级认识
查看>>
3、ASP.NET MVC入门到精通——Entity Framework增删改查
查看>>
C/C++中手动获取调用堆栈【转】
查看>>
Linux中断(interrupt)子系统之五:软件中断(softIRQ)【转】
查看>>
使用T4模板生成POCO类
查看>>
图像的马赛克艺术化
查看>>
DWZ中Tree树形菜单的treeCheck如何获取返回值解决方案
查看>>
欧几里得求最大公约数
查看>>
浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色
查看>>
线程2种方式的差异
查看>>
JQUERY判断操作CHECKBOX选中、取消选中、反选、第二次无法选中的问题
查看>>
Javascript设计模式之匿名函数与闭包
查看>>
创建用户和授权
查看>>
tensorflow中slim模块api介绍
查看>>
读代码整洁之道
查看>>
Extended WPF Toolkit 新控件介绍
查看>>