Android的图片压缩

Android的图片压缩的几种方式:质量压缩,尺寸压缩,采样率压缩,通过NDK调用libjpeg库进行压缩!

质量压缩

通过设置bitmap options属性,降低图片的质量,但是像素不会减少

    public static void compressImageToFile(Bitmap bmp,File file) {// 0-100 100为不压缩int options = 20;ByteArrayOutputStream baos = new ByteArrayOutputStream();bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);try {FileOutputStream fos = new FileOutputStream(file);fos.write(baos.toByteArray());fos.flush();fos.close();} catch (Exception e) {e.printStackTrace();}}

尺寸压缩

通过减小图片的尺寸,减小图片像素以及内存的使用,来进行压缩!

  public static void compressBitmapToFile(Bitmap bmp, File file){// 尺寸压缩倍数,值越大,图片尺寸越小int ratio = 8;// 压缩Bitmap到对应尺寸Bitmap result = Bitmap.createBitmap(bmp.getWidth() / ratio, bmp.getHeight() / ratio, Config.ARGB_8888);Canvas canvas = new Canvas(result);Rect rect = new Rect(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();}}

采样率压缩

通过关键字inJustDecodeBounds 加载bmp,设置bmp的inSampleSize 参数,控制图片采样率进行压缩,这里的decodeFile是使用Android自己的native压缩方法!

 public static void compressBitmap(String filePath, File file){// 数值越高,表示图片像素越低int inSampleSize = 10;BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = false;
//          options.inJustDecodeBounds = true;//注意,如果为true的时候不会真正加载bmp,只能得到图片的宽高信息。//采样率options.inSampleSize = inSampleSize;Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);ByteArrayOutputStream baos = new ByteArrayOutputStream();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();}}

LIBJPEG进行压缩

Libjpeg是95年开源的一个图片处理库,基于C语言的!
我们通常会有一个一个疑问:为什么同样大小的照片,IPHONE拍出来的照片会比Android的要清晰,以前一直搞不明白,通过网上查阅资料终于明白其历史来源!原因是:google犯的一个”错误”!

其实IPHONE与Android的图片压缩都是使用图片压缩都是基于LibJPE库,只是google思前想后最终将libjpeg库的一个参数arith_code(是否使用哈夫曼编码)设置为false,采用了定长编码压缩,这样就导致图片会比IOS端大一些!google这样做是基于哈夫曼编码相对会耗性能,以前我们的手机设备cpu内存比较吃紧,所以遗弃了哈夫曼编码算法!但是现在对于我们的手机设备来说,cpu已经大大的解放,在损耗一丢丢的性能而去追求良好体验的代价是不大的!
所以说,任何事情存在都是有其历史原因的,存在即合理~!

使用Libjpeg

Libjpeg是C语言写的,需要交叉编译so或者.a到Android平台使用.下面是使用步骤!

1.下载源码

    https://ijg.org

2.编译链接库

将下载好了源代码传到linux,进行编译!步骤:修改文件可执行权限./configure 检查环境编写脚本:1 #!/bin/bash2 export NDK=/usr/temptest/ndk/android-ndk-r10e3 export CPU=arm4 export PREFIX=$(pwd)/android2/$CPU7 ./configure --prefix=$PREFIX8 --enable-static \9 --disable-shared                                                                                                                                                                           10 make clean11 make12 make install执行脚本,半分钟就可以完成,可以看到so .a文件!

3.使用Libjpeg库
NDK环境相关的这里就不讲了,大家可以看我的其他博客有写!下面写NDK调用:

1.将android的bitmap解码,并转换成RGB数据,去除alpha
2.JPEG对象分配空间以及初始化
3.指定压缩数据源
4.获取文件信息
5.为压缩文件设置参数,比如图像大小、类型、颜色空间
6.开始压缩
jpeg_start_compress()
7.压缩结束
jpeg_finish_compress()
8.释放资源
void Java_test_jpeg_JPEGUtil_compress(JNIEnv* env,jclass thiz, jobject bitmapcolor, int w, int h, int quality,jstring fileNameStr) {BYTE *pixelscolor;//1.锁定画布,将bitmap里面的所有像素信息读取出来,并转换成RGB数据,保存到二维byte数组(pixelscolor)里面AndroidBitmap_lockPixels(env,bitmapcolor,(void**)&pixelscolor);//2.解析每一个像素点里面的rgb值(去掉alpha值),保存到一维数组data里面BYTE *data;BYTE r,g,b;data = (BYTE*)malloc(w*h*3);//每一个像素都有三个信息RGBBYTE *tmpdata;//临时保存data的首地址tmpdata = data;int i=0,j=0;int color;for (i = 0; i < h; ++i) {for (j = 0; j < w; ++j) {//解决掉alpha//获取二维数组的每一个像素信息首地址color = *((int *)pixelscolor);//通过地址取值//0~255:
//          a = ((color & 0xFF000000) >> 24);r = ((color & 0x00FF0000) >> 16);g = ((color & 0x0000FF00) >> 8);b = ((color & 0x000000FF));//改值!!!----保存到data数据里面*data = b;*(data+1) = g;*(data+2) = r;data = data + 3;//一个像素包括argb四个值,每+4就是取下一个像素点pixelscolor += 4;}}//处理bitmap图形信息方法2 解锁AndroidBitmap_unlockPixels(env,bitmapcolor);generateJPEG(tmpdata,w,h,quality,fileName,optimize);
}void generateJPEG(BYTE* data, int w, int h, int quality,const char* outfilename, jboolean optimize) {//jpeg的结构体,保存的比如宽、高、位深、图片格式等信息struct jpeg_compress_struct jcs;//当读完整个文件的时候就会回调my_error_exit这个退出方法。setjmp是一个系统级函数,是一个回调。struct my_error_mgr jem;jcs.err = jpeg_std_error(&jem.pub);jem.pub.error_exit = my_error_exit;if (setjmp(jem.setjmp_buffer)) {return ;}//初始化jsc结构体jpeg_create_compress(&jcs);//打开输出文件 wb:可写byteFILE* f = fopen(outfilename, "wb");if (f == NULL) {return ;}//设置结构体的文件路径jpeg_stdio_dest(&jcs, f);jcs.image_width = w;//设置宽高jcs.image_height = h;//看源码注释,设置哈夫曼编码:/* TRUE=arithmetic coding, FALSE=Huffman */jcs.arith_code = false;/* 颜色的组成 rgbjcs.input_components = 3;//设置结构体的颜色空间为rgbjcs.in_color_space = JCS_RGB;//设置默认参数jpeg_set_defaults(&jcs);//是否采用哈弗曼表数据计算 品质相差5-10倍jcs.optimize_coding = optimize;//设置质量jpeg_set_quality(&jcs, quality, true);//开始压缩,第二个参数表示是否写入全部像素jpeg_start_compress(&jcs, TRUE);JSAMPROW row_pointer[1];int row_stride;//一行的rgb数量row_stride = jcs.image_width * 3;while (jcs.next_scanline < jcs.image_height) {//得到一行的首地址row_pointer[0] = &data[jcs.next_scanline * row_stride];//此方法会将jcs.next_scanline加1//row_pointer就是一行的首地址//1表示写入的行数jpeg_write_scanlines(&jcs, row_pointer, 1);}//结束jpeg_finish_compress(&jcs);jpeg_destroy_compress(&jcs);//销毁回收内存fclose(f);
}

几种压缩方法对比

对比几种压缩算法,通过比较,在图片大小以及图片清晰度进行对比,Libjpeg效果更佳!

Android LibJpeg图片压缩相关推荐

  1. Android中图片压缩分析(上)

    此文章首发:https://mp.weixin.qq.com/s/QZ-XTsO7WnNvpnbr3DWQmg 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种: ...

  2. Android中图片压缩方案详解

    如感觉排版不舒服,可移步至此处查看 图片的展示可以说在我们任何一个应用中都避免不了,可是大量的图片就会出现很多的问题,比如加载大图片或者多图时的OOM问题,可以移步到Android高效加载大图.多图避 ...

  3. Android 高效图片压缩

    使用libjpeg-turbo进行图片压缩 1. JEPG 是什么? 相信有一部分使用 iPhone 手机用微信发送图片的时候,明明图片大小只有 1M ,但清晰度比 Android 手机 5 M 图片 ...

  4. Android的图片压缩并上传

    Android开发中上传图片很常见,一般为了节省流量会进行压缩的操作,本篇记录一下压缩和上传的方法. 图片压缩的方法 : import java.io.ByteArrayOutputStream; i ...

  5. Android之图片压缩

    转载注明出处:http://blog.csdn.net/xiaohanluo/article/details/52485037 1. 引子 前几天跟服务端的一个妹子联调接口,服务器配置一张图片,几十K ...

  6. Android关于图片压缩

    关于图片压缩 [Android图片压缩(质量压缩和尺寸压缩)&Bitmap转成字符串上传] http://blog.csdn.net/jdsjlzx/article/details/44228 ...

  7. Android BitMap图片压缩

    最近在网上看了一些关于图片压缩的博客,自己也动手实验了一遍,也算事对图片压缩有了一个了解,打算写个博客记录一下.文末附上参考链接. Android中涉及到图片的话一般都会用到BitMap类和Bitma ...

  8. Android图片系列-2.Android App图片压缩、裁剪分析整理

    移动端常用的图片格式有PNG和JPEG,目前ios手机和大部分安卓手机拍照生成的图片默认格式都是JPEG.我们开发APP的时候通常使用的是PNG,这可能是考虑到图片质量效果.PNG图片是无损压缩格式, ...

  9. Android实现图片压缩并上传到服务器

    最近公司又叫开发了一个新项目,这个项目中上传图片用的蛮多的,于是整理一下,记录自己的心得体验 刚入手的时候,对于图片的大小还没有概念,(以前上传图片都是用户头像,对大小没什么要求),心想之间上传就是了 ...

最新文章

  1. 记录一次生产环境下的jvm内存泄露问题和分析解决过程!
  2. Silverlight学习之——事件编程
  3. 简单io应用—流水灯控制_制作简单有趣的可调速流水灯
  4. WebSocket服务器和客户端的一对多连接
  5. java 的“mwq”_java的对象模型 - osc_mwqvsfzo的个人空间 - OSCHINA - 中文开源技术交流社区...
  6. IoTSharp 2.0 发布
  7. 吴裕雄 python 机器学习——数据预处理过滤式特征选取SelectPercentile模型
  8. flutter html 加载_Flutter开发:项目加载本地html文件的步骤
  9. Egret入门学习日记 --- 第十三篇(书中 5.2~5.3节 内容)
  10. PowerShell: 如何使用powershell处理Excel
  11. 百度深度学习工程师认证(已通过)
  12. 64位mysql下载百度云_MySQL下载与安装
  13. linux使用certbot,如何自动续期~
  14. Python数据分析(Pandas)
  15. C语言教你怎么改变字体颜色
  16. weblogic 漏洞复现
  17. 新的掌舵手已就位,汽车之家这艘船将驶向何方?
  18. Python 用pygame 做一个游戏的开始界面(小白第一篇博客)
  19. 远程计算机桌面登录拒绝访问,win7远程界面显示拒绝访问
  20. 基于E-PUCK 2.0多智能体自主协同 高频投影定位系统

热门文章

  1. 程序员进阶之路 --- 如何超过大多数人?
  2. epoll的实现原理
  3. 计算机开机速度慢是什么原因,电脑启动慢是什么原因造成(4招优化电脑的开机速度,10秒...
  4. 农行人工智能机器人安安_农业银行信用卡新卡种,只要有电信号码通通3万!...
  5. TypeScript入门指南:从JS到TS的转变
  6. 同步延时问题解决方案
  7. mysql的单表和多表练习
  8. VSCode配置lauch.json导入自定义的包
  9. java1.8 离线下载安装_JDK1.8下载与安装(完整的图文教程)
  10. 大数据时代下的征信,关系到生活中的每一个人