性能优化-Bitmap简单处理分析
来源:互联网 发布:淘宝网店的swot分析 编辑:程序博客网 时间:2024/06/01 10:37
BitmapFactory源码大致分析:
- BitmapFactory有一个静态内部类Options,有以下属性:
inBitmap:在解析Bitmap时重用该Bitmap,不过必须等大的Bitmap而且inMutable须为trueinPreferredConfig:Bitmap.Config.ARGB_8888等inMutable:配置Bitmap是否可以更改,比如:在Bitmap上隔几个像素加一条线段inJustDecodeBounds:为true仅返回Bitmap的宽高等属性inSampleSize:须=1,表示Bitmap的压缩比例,如:inSampleSize=4,将返回一个是原始图的1/16大小的BitmapinDither:是否抖动,默认为falseinPremultiplied:默认为true,一般不改变它的值inDensity:Bitmap的像素密度inTargetDensity:Bitmap最终的像素密度inScreenDensity:当前屏幕的像素密度inScaled:是否支持缩放,默认为true,当设置了这个,Bitmap将会以inTargetDensity的值进行缩放inPurgeable:当存储Pixel的内存空间在系统内存不足时是否可以被回收inInputShareable:inPurgeable为true情况下才生效,是否可以共享一个InputStreaminPreferQualityOverSpeed:为true则优先保证Bitmap质量其次是解码速度outWidth:返回的Bitmap的宽outHeight:返回的Bitmap的高inTempStorage:解码时的临时空间,建议16*1024
BitmapFactory中重要的方法:
Bitmap decodeFile(String pathName)
Bitmap decodeFile(String pathName, Options opts)
Bitmap decodeResource(…)
Bitmap decodeByteArray(…)
Bitmap decodeStream(…)
Bitmap decodeFileDescriptor(…)其实最终还是调用decodeStream(…)来加载图片,而decodeStream(…)则是调用native方法。而在调用decodeResource在解析时还会多调用一个方法:
public static Bitmap decodeResourceStream(Resources res, TypedValue value, InputStream is, Rect pad, Options opts) { if (opts == null) { opts = new Options(); } if (opts.inDensity == 0 && value != null) { final int density = value.density; if (density == TypedValue.DENSITY_DEFAULT) { opts.inDensity = DisplayMetrics.DENSITY_DEFAULT; } else if (density != TypedValue.DENSITY_NONE) { opts.inDensity = density; } } if (opts.inTargetDensity == 0 && res != null) { opts.inTargetDensity = res.getDisplayMetrics().densityDpi; } return decodeStream(is, pad, opts); }
它主要是对Options进行处理了,在得到 opts.inDensity 属性的前提下,如果我们没有对该属性设定值,那么将
opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
赋定这个默认的Density值,这个默认值为160,为标准的dpi比例,即在Density=160的设备上1dp=1px,
还有这么一行
opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
对 opts.inTargetDensity 进行了赋值,该值为当前设备的densityDpi值,所以说在decodeResourceStream方法中主要两件事事:
- 对opts.inDensity赋值,没有则赋默认值160、
- 对opts.inTargetDensity赋值,没有则赋当前设备的densityDpi值
重点来了,之后参数将传入decodeStream方法,该方法中在调用native方法进行解析Bitmap后会调用这个方法
setDensityFromOptions(bm, opts);
该方法主要就是把刚刚赋值过的两个属性inDensity和inTargetDensity给Bitmap进行赋值,不过并不是直接赋给Bitmap就完了,中间有个判断,当inDensity的值与inTargetDensity或与设备的屏幕Density不相等时,则将应用inTargetDensity的值,如果相等则应用inDensity的值。
所以总结来说, setDensityFromOptions 方法就是把 inTargetDensity 的值赋给Bitmap,不过前提是opts.inScaled = true;
进过上面的分析,可以得出这样一个结论:
- 在不配置Options的情况下:
- decodeFile、decodeStream在解析时不会对Bitmap进行一系列的屏幕适配,解析出来的将是原始大小的图
- decodeResource在解析时会对Bitmap根据当前设备屏幕像素密度densityDpi的值进行缩放适配操作,使得解析出来的Bitmap与当前设备的分辨率匹配,达到一个最佳的显示效果,并且Bitmap的大小将比原始的大。
下面简单介绍几种压缩方式:
- 质量压缩
/** * 原理:通过算法抠掉(同化)了图片中的一些某个些点附近相近的像素, * 达到降低质量介绍文件大小的目的。 * 减小了图片质量 * * 注意:它其实只能实现对file的影响, * 对加载这个图片出来的bitmap内存是无法节省的,还是那么大。 * 也就是width*height,对于质量压缩, * 并不会改变图片的真实的像素(像素大小不会变)。 * * 使用场景:将图片压缩后保存到本地,或者将图片上传到服务器。根据实际需求来。 */ public void qualitCompress(){ BitmapFactory.Options options = new BitmapFactory.Options(); Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options); //压缩图片 compressImageToFile(bitmap, new File(sdFile,"qualityCompress.jpeg")); } public static void compressImageToFile(Bitmap bmp,File file){ //0~100 越大代表压缩的越少 int quality = 50; ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, quality , baos ); try { FileOutputStream fos = new FileOutputStream(file); fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } }
- 尺寸压缩
/** * 通过减少单位尺寸的像素值,正真意义上的降低像素。 * 使用场景:缓存缩略图的时候(头像处理) */ public void sizeCompress(View v){ BitmapFactory.Options options = new BitmapFactory.Options(); Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options); compressBitmapToFileBySize(bitmap, new File(sdFile,"sizeCompress.jpeg")); } public static void compressBitmapToFileBySize(Bitmap bmp,File file){ //压缩尺寸倍数,值越大,图片的尺寸就越小 int ratio = 4; Bitmap result = Bitmap.createBitmap(bmp.getWidth()/ratio, bmp.getHeight()/ratio, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(result); //这里举例 RectF rect = new RectF(0, 0, bmp.getWidth()/ratio, bmp.getHeight()/ratio); canvas.drawBitmap(bmp, null, rect , null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); result.compress(Bitmap.CompressFormat.JPEG, 100, baos); try { FileOutputStream fos = new FileOutputStream(file); fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } }
- 采样率压缩
/** * 设置图片的采样率,降低图片像素 * @param filePath * @param file */ public static void compressBitmap(String filePath, File file){ // 数值越高,图片像素越低 int inSampleSize = 8; BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false;// options.inJustDecodeBounds = true;//为true的时候不会真正加载图片,而是得到图片的宽高信息。 //采样率 options.inSampleSize = inSampleSize; Bitmap bitmap = BitmapFactory.decodeFile(filePath, options); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 把压缩后的数据存放到baos中 bitmap.compress(Bitmap.CompressFormat.JPEG, 100 ,baos); try { if(file.exists()) { file.delete(); } else { file.createNewFile(); } FileOutputStream fos = new FileOutputStream(file); fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } }
- 性能优化-Bitmap简单处理分析
- 【Android应用开发技术:图像处理】Bitmap显示性能优化分析
- Bitmap性能优化问题
- ANDROID性能优化:Bitmap
- Bitmap的处理优化
- bitmap图片处理优化
- 简单的bitmap处理
- Android:BitMap的性能优化
- Bitmap图片压缩优化处理
- Android性能优化之:加载Bitmap优化
- Bitmap的加载简单优化
- Bitmap的简单特效处理
- 优化SilverLight 处理性能
- 创建bitmap时的优化处理
- oracle简单性能优化
- Android性能优化分析
- 服务端性能分析优化
- Web性能优化分析
- Request与Response常用方法总结
- Linux安装cmake&doxygen
- Java泛型详解,通俗易懂只需5分钟
- Android实现推送方式解决方案
- 欢迎使用CSDN-markdown编辑器
- 性能优化-Bitmap简单处理分析
- 输入的时候被键盘遮挡的问题
- 异构多核处理器开发嵌入式应用入门
- Maximum GCD UVA
- bootstrap中下拉组件没反应
- 随记(1)
- SQLException for SQL [n/a]; SQL state [HY000]; error code [1366];
- 浅谈spring框架(三)
- 怎么让div的高度自适应屏幕的高度