关于Android中图片compress的有关问题
2013-08-05 19:26
246 查看
在Android中图片的三种类型形式是Bitmap,Drawable和byte[],Google原始的代码中,存在联系人数据库里面的联系人头像就是byte[]类型的。但是为保证数据库不会过大,图片都是要经过压缩之后再保存的。
众所周知,联系人都是有导出导入功能的,导出时就是取的数据库中保存的压缩过的头像,那么如果导入时再次压缩,联系人头像经过多次导出导入之后,头像就会越来越模糊。产生这种情况的原因是导入时和新建联系人设置头像时都走了同一个压缩方法,而且根本没办法区分是新建联系人还是导入。那么通过变量来区分是行不通的,或者说是代价太大。经过输出LOG发现,两者在压缩前后byte[]的长度,即头像的实际文件大小变化是不同的。也就是说,新建联系人时,头像压缩前比压缩后大,而导入恰恰相反。那么就可以以此区分是新建还是导入。产生这种情况原因如下:
众所周知,联系人都是有导出导入功能的,导出时就是取的数据库中保存的压缩过的头像,那么如果导入时再次压缩,联系人头像经过多次导出导入之后,头像就会越来越模糊。产生这种情况的原因是导入时和新建联系人设置头像时都走了同一个压缩方法,而且根本没办法区分是新建联系人还是导入。那么通过变量来区分是行不通的,或者说是代价太大。经过输出LOG发现,两者在压缩前后byte[]的长度,即头像的实际文件大小变化是不同的。也就是说,新建联系人时,头像压缩前比压缩后大,而导入恰恰相反。那么就可以以此区分是新建还是导入。产生这种情况原因如下:
1.Bitmap和byte[]之间的相互转换方法
private Bitmap byteToBitmap(byte[] bitmapToByte) { // TODO Auto-generated method stub return BitmapFactory.decodeByteArray(bitmapToByte, 0, bitmapToByte.length); }
private byte[] bitmapToByte(Bitmap bitmap) { // TODO Auto-generated method stub ByteArrayOutputStream baos =new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);//PNG格式100%压缩,实际就是转换为byte[],占用同样大小的内存 byte[] result = baos.toByteArray(); return result; }
2.图片压缩方法
private byte[] bitmapCompress(Bitmap bitmap,int quality) { // TODO Auto-generated method stub ByteArrayOutputStream baos =new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);//JPEG格式95%压缩 byte[] result = baos.toByteArray(); return result; }
3.插入数据库前头像处理流程
private boolean processPhoto(ContentValues values) { byte[] originalPhoto = values.getAsByteArray(Photo.PHOTO); if (originalPhoto != null) { try { Bitmap tmpBitmap = byteToBitmap(originalPhoto); byte[] tmpByte = bitmapToByte(tmpBitmap);//获取tmpBitmap的实际文件大小 byte[] compressedPhoto = bitmapCompress(tmpBitmap,95); values.put(Photo.PHOTO, originalPhoto.length<compressedPhoto.length?originalPhoto:compressedPhoto); return true; } catch (IOException ioe) { Log.e(TAG, "Could not process photo for insert or update", ioe); } } return false; }
其中ContentValues对象是保存插入到数据库中的对象。新建联系人时originalPhoto,tmpByte,compressedPhoto三者之间的length大小为originalPhoto=tmpByte>compressedPhoto,而导入联系人时三者关系为originalPhoto<compressedPhoto<tmpByte,所以通过originalPhoto.length<compressedPhoto.length?originalPhoto:compressedPhoto存入数据库的数据,新建联系人时是压缩过的,导入联系人时是未压缩过的。
其中的原理是导入时的originalPhoto是新建联系人经过JPEG压缩的compressedPhoto,通过JPEG压缩的图片失真比较严重,而且Bitmap在内存中是完全没有被压缩的,所以导入时的originalPhoto远远小于tmpByte,而tmpByte经过100%压缩,才能得到originalPhoto的大小,否则就会比originalPhoto大。于是导入时,length最小的originalPhoto便是未被压缩的。
相关文章推荐
- 有关asp.net获取android端上传的图片问题
- 关于解决android图片设置时outofmemery的问题!!!!!!!!!!
- 关于Android使用TextView+ImageSpan同一行文字图片居中的问题
- 关于android在图片上写文字的问题
- 关于第三方应用(Android平台)通过微信分享文字、图片的问题研究。
- 【游戏开发备注之一】关于Cocos2dx_v1.x版本iphone与Android运行出现图片白块、添加GameCenter报错问题及编译Android闪退的解决办法&&CCLOG与CClog的区别
- 关于Java后台处理android上传图片的问题
- android红米等关于读取本地文件夹图片获取路径的问题的解决
- 关于android的.9.png图片的问题
- 关于Android资源图片存放位置的问题
- 关于android 调用系统图片浏览器并返回图片路径问题
- 关于android阿里云上传图片报错初始化错误的问题
- 【史上最简单】android硬件加速——关于图片过大无法显示,直接变黑色问题
- Android 关于RecyclerView瀑布流显示图片时Item切换、闪烁等问题优化
- 关于android webview 图片使用同一个src导致只加载第一张的问题
- 关于Android开发中图片资源文件夹drawable中图片与资源ID号出现对不上的问题
- Android 关于背景图片的透明度问题
- 关于android gridview 加载大量图片的OOM问题解决方案
- Android开发中关于UI图片资源的问题
- 关于向Android项目中的drawable下添加图片却无法使用的问题