关于Android中图片compress的有关问题

来源:互联网 发布:广数g76车螺纹编程实例 编辑:程序博客网 时间:2024/05/17 03:58

        在Android中图片的三种类型形式是Bitmap,Drawable和byte[],Google原始的代码中,存在联系人数据库里面的联系人头像就是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便是未被压缩的。
原创粉丝点击