您的位置:首页 > 其它

关于Bitmap对象,尺寸压缩,质量压缩

2016-01-21 17:56 218 查看
一:在什么时候我们需要对图片质量压缩?

一般情况下,我们在网上上传图片的时候要压缩图片的质量(体积),因为有的时候服务器对图片大小有限制

二: 在什么时候我们需要对图片尺寸压缩?

我们从服务器请求的图片通常要转化为Bitmap对象,如果该图片尺寸越大,通常所需要的Bitmap也越大,为防止oom,所以通常我们要对图片进行尺寸压缩

三: 在Bitmap中我们要用到BitmapFactory.Options这个类,所以对这个类的几个属性先进行说明一下

options.inJustDecodeBounds = true;//设置为true后,在通过BitmapFactory返回对象的时候,并不会真的返回你一个bitmap,而是会返给这个bitmap的宽和高,防止oom

options.inPurgeable = true;//设置为true 当系统内存不足时可以回收bitmap对象,但是当需要重新编译的时候可以访问存储bitmap的原始数据

opts.inInputShareable = true;// 设置是否深拷贝,与inPurgeable结合使用

options.inPreferredConfig = Config.RGB_565;//默认值ARGB_8888改为RGB_565,节约一半内存。

Bitmap.Config ARGB_4444:每个像素占四位,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位

Bitmap.Config ARGB_8888:每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位

Bitmap.Config RGB_565:每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位

Bitmap.Config ALPHA_8:每个像素占四位,只有透明度,没有颜色

四:图片尺寸压缩的写法

图片压缩的原理是抽取像素点,分辨率(像素密度大小不变),只改变图片的尺寸

/**
*
* @param imagePath
* @param maxWidth
* @param maxHeight
* @return
*/
@SuppressWarnings("finally")
public static Bitmap getImageThumbnail(String imagePath, int maxWidth,
int maxHeight, boolean isDeleteFile) {
Bitmap bitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inPurgeable = true;
options.inInputShareable = true;
options.inPreferredConfig = Config.RGB_565;
bitmap = BitmapFactory.decodeFile(imagePath, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
FileInputStream inputStream = null;
File file = new File(imagePath);
try {
if(file != null && file.exists()){
inputStream = new FileInputStream(file);
bitmap = BitmapFactory.decodeStream(inputStream, null,options);
if(isDeleteFile){
file.delete();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
}


</pre><pre name="code" class="java">
五:图片质量压缩的写法

图片质量压缩的,会使图片占用内存减小(file),像素数不变,所生成bitmap对象大小不变
<pre name="code" class="java">/**
* 质量压缩图片,图片占用内存减小,像素数不变,常用于上传
* @param image
* @param size 期望图片的大小,单位为kb
* @param options 图片压缩的质量,取值1-100,越小表示压缩的越厉害,如输入30,表示压缩70%
* @return
*/
private static Bitmap compressImage(Bitmap image,int size,int options) {

ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
image.compress(Bitmap.CompressFormat.JPEG, 80, baos);
// 循环判断如果压缩后图片是否大于100kb,大于继续压缩
while (baos.toByteArray().length / 1024 > size) {
options -= 10;// 每次都减少10
baos.reset();// 重置baos即清空baos
// 这里压缩options%,把压缩后的数据存放到baos中
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
// 把压缩后的数据baos存放到ByteArrayInputStream中
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
// 把ByteArrayInputStream数据生成图片
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
}



</pre><pre name="code" class="java">六:两种方法的混合使用
<pre name="code" class="java"> /**
* 二次压缩,先按照像素压缩再按照质量压缩
* @param imgUrl 图片路径
* @param reqWidth 期望宽度 可以根据市面上的常用分辨率来设置
* @param size 期望图片的大小,单位为kb
* @param quality 图片压缩的质量,取值1-100,越小表示压缩的越厉害,如输入30,表示压缩70%
* @return Bitmap 压缩后得到的图片
*/
public static Bitmap compressBitmap(String imgUrl,int reqWidth,int size,int quality){
// 创建bitMap
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imgUrl, options);
int height = options.outHeight;
int width = options.outWidth;
int reqHeight;
reqHeight = (reqWidth * height) / width;
// 在内存中创建bitmap对象,这个对象按照缩放比例创建的
options.inSampleSize = calculateInSampleSize(
options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
Bitmap bm = BitmapFactory.decodeFile(
imgUrl, options);
Bitmap mBitmap = compressImage(Bitmap.createScaledBitmap(
bm, 480, reqHeight, false),size,quality);
return  mBitmap;
}
</pre><pre name="code" class="java">
/**
     * 计算像素压缩的缩放比例
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    private static int calculateInSampleSize(BitmapFactory.Options options,
                                             int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            if (width > height) {
                inSampleSize = Math.round((float) height / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) width / (float) reqWidth);
            }
        }
        return inSampleSize;
    }



</pre><pre name="code" class="java">
</pre><pre name="code" class="java">
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: