Android 图片压缩

一 前言

        在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩;质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成缩略图。
两种方法都实装在了我的项目中,结果却发现在质量压缩的模块中,本来1.9M的图片压缩后反而变成3M多了,很是奇怪,再做了进一步调查终于知道原因了。下面这个博客说的比较清晰:
android图片压缩总结:
           总结来看,图片有三种存在形式:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap,所谓的 质量压缩,它其实只能实现对file的影响,你可以把一个 file转成bitmap再转成file,或者直接将一个bitmap转成file时,这个最终的file是被压缩过的,但是中间的bitmap并没有被压缩(或者说几乎没有被压缩,我不确定),因为bigmap在内存中的大小是按像素计算的,也就是width * height,对于质量压缩,并不会改变图片的像素,所以就算质量被压缩了,但是bitmap在内存的占有率还是没变小,但你做成file时,它确实变小了;而尺寸压缩由于是减小了图片的像素,所以它直接对bitmap产生了影响,当然最终的file也是相对的变小了

二 压缩方式

1 质量压缩
public static void compressQuality(Bitmap bmp , File saveFile , int scale){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//压缩后的数据保存到baos中
bmp.compress(Bitmap.CompressFormat.JPEG, scale, baos);
FileOutputStream os = null;
try {
os = new FileOutputStream(saveFile);
os.write(baos.toByteArray());
os.flush();
os.close();
baos.close();
} catch (FileNotFoundException e) {
LogUtil.logErrorMessage(TAG,e.getMessage());
} catch (IOException e) {
LogUtil.logErrorMessage(TAG,e.getMessage());
}finally {
try {
if (null != os){
os.close();
}
baos.close();
} catch (IOException e) {
LogUtil.logErrorMessage(TAG,e.getMessage());
}

}
}
说明: 第一个参数为需要压缩的bitmap图片对象,第二个参数为压缩后图片保存的位置, 第三个参数scale压缩比例,其值 0-100,100为不压缩,值越小压缩也严重。
2 尺寸压缩
public static void compressSize(Bitmap bmp , File saveFile, int scale){
//压缩Bitmap到对应尺寸
Bitmap compressBitmap = Bitmap.createBitmap(bmp.getWidth() / scale, bmp.getHeight() / scale,Bitmap.Config.ARGB_8888);
// 原图的裁剪区域
Rect srcRect = new Rect(0, 0, bmp.getWidth(), bmp.getHeight());
//压缩后的区域
Rect compressRect = new Rect(0, 0, bmp.getWidth() / scale, bmp.getHeight() / scale);
//创建画布,用来绘制图片
Canvas canvas = new Canvas();
canvas.setBitmap(compressBitmap);
canvas.drawBitmap(bmp,srcRect,compressRect,null);
//压缩后的数据保存到baos中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
compressBitmap.compress(Bitmap.CompressFormat.JPEG,100,baos);
FileOutputStream os = null;
try {
os = new FileOutputStream(saveFile);
os.write(baos.toByteArray());
os.flush();
os.close();
baos.close();
} catch (FileNotFoundException e) {
LogUtil.logErrorMessage(TAG,e.getMessage());
} catch (IOException e) {
LogUtil.logErrorMessage(TAG,e.getMessage());
}finally {
try {
if (null != os){
os.close();
}
baos.close();
} catch (IOException e) {
LogUtil.logErrorMessage(TAG,e.getMessage());
}

}
//释放内存回收资料
compressBitmap.recycle();
System.gc();

}
       说明:第一个参数为需要压缩的bitmap图片对象,第二个参数为压缩后图片保存的位置,第三个参数scale尺寸压缩倍数,值越大压缩也严重;从上述代码也可以看出尺寸压缩针对的对象是bitmap,对原先的图片Bitmap对象进行尺寸缩减,相应的图片的大小、像素也就减小了。
设置图片的采样率,降低图片像素
public static void compressBitmap(String filePath, File file , int inSampleSize){
// 数值越高,图片像素越低
BitmapFactory.Options options = new BitmapFactory.Options();
//采样率
options.inSampleSize = inSampleSize;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 把压缩后的数据存放到baos中
bitmap.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();
}
}
说明:参数一  图片的位置;参数二 压缩后图片保存的位置;参数三 采样率数值越高,图片像素越低

三 JNI调用libjpeg库压缩

JNI静态调用 bitherlibjni.c 中的方法来实现压缩,首先要添加os库到lib中,在app的build添加如下代码:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
再者,在工具类中添加声明libjpeg库:
static {
System.loadLibrary("jpegbither");
System.loadLibrary("bitherjni");
}
再者添加native方法:
private static native String compressBitmap(Bitmap bit, int w, int h, int quality, byte[] fileNameBytes,
boolean optimize);
参数说明如下:
* @param bit 需要压缩的Bitmap对象
* @param w 图片宽度
* @param h 图片高度
* @param quality 压缩质量0-100
* @param fileNameBytes 压缩后要保存的文件地址
* @param optimize 是否采用哈弗曼表数据计算 品质相差5-10倍
然后就可以调用该方法了。
工具类封装点击查看 NativeUtil

四 ThumbnailUtils系统工具类视频缩略图

1 Bitmap createVideoThumbnail(String filePath, int kind)

创建一张视频的缩略图。如果视频已损坏或者格式不支持可能返回null。

filePath:视频文件路径

kind:文件种类,可以是 MINI_KIND 或 MICRO_KIND

 
 

Bitmap extractThumbnail(Bitmap source, int width, int height, int options)

创建所需尺寸居中缩放的位图。

source: 需要被创造缩略图的源位图对象

width: 生成目标的宽度

height: 生成目标的高度

options:在缩略图抽取时提供的选项

 
 
 Bitmap extractThumbnail(Bitmap source, int width, int height)   

创建所需尺寸居中缩放的位图。
source: 需要被创造缩略图的源位图对象
width: 生成目标的宽度
height: 生成目标的高度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值