众所周知,android端开发 图片问题一直都是比较重视的
图片处理好不好直接关系到内存和性能的好坏
本人也在查阅相关的资料,根据自己的理解做的总结 不足 错误之处还请大家留言改正.....
图片性能之三级缓存篇
1. 什么是图片的三级缓存?
图片的三级缓存主要是指在内存,文件和网络
2.三级缓存的具体实现
大家都知道图片要是从网络获取的话不仅速度慢,消耗流量多,用户体验不好
所以我们通常采用的方法就是分别从内存中,假如内存中不存在 此时就要从本地缓存文件中查询(自定义目录)
当本地文件不存在的时候我们才考虑去网络上加载图片
从网络上获取图片之后再把图片缓存到本地再由本地到内存 最后在展现在用户的面前
总体流程就是
代码如下:
(暂时没时间写代码以后再补)
图片之性能优化篇
图片的优化其实就是内存的优化 处理不好就会引来OOM异常甚至程序崩溃
android中加载图片是个很浪费内存的事情,因此我查询了很多的方法,一下列举几种比较常用的
1.图片的缩放
1).BitmapFactory和BitmapFactory.Options。
首先从服务器获取到图片,我们可以获取到图片的宽高信息,再获取当前手机的宽和高可以通过
<span style="white-space:pre"> <span style="font-size:12px;"> </span></span><span style="font-size:18px;">int screenWidth = 0;
int screenHeight = 0;
Display display = getWindowManager().getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();</span>
根据图片和手机屏幕的宽高比进行缩放
</pre><p><pre name="code" class="java"> <span style="font-size:18px;"> <span style="white-space:pre"> </span>Options opts=new BitmapFactory.Options();
opts.inSampleSize=(图片的宽度/屏幕的宽度+图片的高度/屏幕的高度)/2;
BitmapFactory.decodeFile("图片路径", opts);</span>
2).使用Bitmap加Matrix来缩放
<span style="white-space:pre"> </span>/* 设置图片缩小的比例 */
double scale=0.8;
/* 计算出这次要缩小的比例 */
scaleWidth=(float) (scaleWidth*scale);
scaleHeight=(float) (scaleHeight*scale);
/* 产生reSize后的Bitmap对象 */
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizeBmp = Bitmap.createBitmap(bmp,0,0,bmpWidth,
bmpHeight,matrix,true);
2.图片的config设置
图片的内存大小除了跟大小有关系还跟材质有关系
可以通过设置config属性来改变图片的大小,达到减少内存的目的
opts.inPreferredConfig=Bitmap.Config.ALPHA_8;
opts.inPreferredConfig=Bitmap.Config.ARGB_4444;
opts.inPreferredConfig=Bitmap.Config.ARGB_8888;
opts.inPreferredConfig=Bitmap.Config.RGB_565;
3.图片的强引用,软引用,弱引用,虚引用(Strong Reference,SoftReference,WeakReference,PhantomReference)(Android3.0以后不支持)
首先将一下这四种引用的区别
强引用(Strong Reference):
强引用是我们编写代码最常见的引用了,比如String a="",简单说强引用就是你不把他置为空,android系统内存不足的时候,系统也不会主动的回收该内存(打死也不回收)
软引用(Soft Reference)
软引用是即使对象没置为空,一旦android系统检测到内存不足的时候,就会把你干掉(不足就干掉)
弱引用(WeakReference)
弱引用就是一旦存储的强引用被删除,该弱引用的对象也将被回收(要死一起死)
虚引用(PhantomReference)
虚引用就是用完一次就回收(一次性筷子)
当然现在android就算使用软引用也没什么效果,在3.0后android推出了LruCache类专门用来缓存图片
4.当然就是你自己的代码规范问题
图片对象用完要及时置为空,可以采用分批加载图片和一次不要加载太多图片到内存,
图片之压缩篇
相信很多小伙伴都会遇到将图片上传到服务器,或者保存到本地,然而图片太大,上传流量消耗大,上传慢
占用空间大,该怎么解决呢? 自然要涉及到图片的压缩 注明:此篇是参照别的博客所写
1.图片存在的几种形式
2).流的形式(即以二进制形式存在于内存中)
3).Bitmap形式
二.常见的压缩方式
- public static void compressBmpToFile(Bitmap bmp,File file){
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int options = 80;//个人喜欢从80开始,
- bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
- while (baos.toByteArray().length / 1024 > 100) {
- baos.reset();
- options -= 10;
- bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
- }
- try {
- FileOutputStream fos = new FileOutputStream(file);
- fos.write(baos.toByteArray());
- fos.flush();
- fos.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- private Bitmap compressBmpFromBmp(Bitmap image) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int options = 100;
- image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
- while (baos.toByteArray().length / 1024 > 100) {
- baos.reset();
- options -= 10;
- image.compress(Bitmap.CompressFormat.JPEG, options, baos);
- }
- ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
- Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
- return bitmap;
- }
- private Bitmap compressImageFromFile(String srcPath) {
- BitmapFactory.Options newOpts = new BitmapFactory.Options();
- newOpts.inJustDecodeBounds = true;//只读边,不读内容
- Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
- newOpts.inJustDecodeBounds = false;
- int w = newOpts.outWidth;
- int h = newOpts.outHeight;
- float hh = 800f;//
- float ww = 480f;//
- int 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;//设置采样率
- newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设
- newOpts.inPurgeable = true;// 同时设置才会有效
- newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
- bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
- // return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩
- //其实是无效的,大家尽管尝试
- return bitmap;
- }