96编辑器旗下产品
找图
终身
ID:0
到期时间:永久
退出登录
您的位置:首页 > 百科管理 > 详情

bitmap压缩算法-libjpeg-turbo 图片压缩

原创:找图网 2023-05-03 04:59:08
  • 记得有一种图片压缩算法,它甚至可以估计图片之外包含什么,这是什么算法?

  • 在我们开发过程中,有可能会遇到拍照、或者从相册中选择图片,要么单选或者多选,然后上传图片到服务器,一般情况下一张图片可能3-4M,如果类似微信朋友圈上传9张图片大约是 35M左右,如果我们上传 35M左右的图片到服务器,可想而知后台的压力有多大,最主要的还是特别耗时,如果是在网速比较慢,那么用户上传图片可能需要4-5分钟,那么用户就会受不了,可能会退出应用。

    比如QQ、WX一般上传图片,会在后台去开一个服务去上传图片,包括没网情况都可以上传或者发布,其实是它们在本地做了一些缓存,并且它们也肯定是做了图片的压缩;

    所以对于我们来说,图片压缩必须要做。我们如果是用BitmapFactory 去压缩尺寸,compress压缩质量,压缩后的图片可能不太清晰,200K以下就不太清晰了;

    早期的图片压缩,都是基于JPEG,但是很耗内存,导致内存吃紧,是因为JPEG里边用了哈弗曼压缩算法,所以最后就把这个压缩算法去掉了,然后使用Skia算法

    像一些第三方应用:比如QQ、WX、华为等,他们的压缩后都在100K以下跟原图没什么区别;

  • 简述JPEG压缩算法

  • JPEG首先对8×8的图象经过DCT变换,其低频分量都集中在左上角,高频分量分布在右下角,由于该低频分量包含了图象的主要信息(如亮度),而高频与之相比,就不那么重要了,所以可以忽略高频分量,从而达到压缩的目的.经过DCT变换后,低频分量集中在左上角,由于两个相邻的8×8子块的DC系数相差很小,所以对它们采用差分编码DPCM,可以提高压缩比,也就是说对相邻的子块DC系数的差值进行编码。8×8的其它63个元素是交流(AC)系数,采用行程编码。得到了DC码字和 AC行程码字,为了进一步提高压缩比,需要对其再进行熵编码,选用Huffman编码,通过查码表,得到相应的码值。也就是JPEG通过DCT变换,进行差分脉冲编码、行程编码和哈佛曼编码达到压缩的目的!

  • libjpeg-turbo 图片压缩

  • android7.0之前,不支持哈夫曼压缩算法,压缩效率不高,因此引入libTurboJpeg库来改善压缩效率。

    安卓底层使用Skia作为它的图片处理引擎,通过对libjpeg进行封装,来进行压缩图片。然而在libjpeg进行压缩图片时,有一个参数,叫optimize_coding,默认为FALSE。关于这个参数,官方的解释是,如果设置为TRUE,在压缩过程中,会计算哈夫曼表,这会显著消耗空间和时间。

    然而这是对于十几年前的设备而言的,现在的设备来做这个计算完全没有压力。因此,只有在安卓7.0之后,才支持了哈夫曼算法。

    开发时,把Java层的Bitmap传递到native层,然后使用 AndroidBitmap API 取出图像所有的argb数据,接着可以舍弃a通道信息,只保留rgb信息到一个新的uint_8数组中,将这个数组作为参数传入jpeg-turbo库中,开启哈夫曼编码,就可以保存到一个新的路径中。

    参考链接:

    我们来看看2,6,8,9,3权值节点构成哈夫曼树的过程。

    初始时候各个节点独立,先将其排序(这里使用优先队列),然后选两个最小节点(抛出)生成一个新的节点,再将其加入优先队列中,此次操作完成后优先队列中有5,6,8,9节点

    重复上面操作,这次结束 队列中有11,8,9节点(排序后8,9,11)

    如果队列为空,那么返回节点,并且这个节点为整个哈夫曼树根节点root。

    否则继续加入队列进行排序。重复上述操作,直到队列为空。

    先统计字符出现的次数,然后将这个次数当成权值按照上面介绍的方法构造一棵哈夫曼树,然后树的根不存,往左为0往右为1每个叶子节点得到的二进制数字就是它的编码,这样频率高的字符在上面更短在整个二进制存储中也更节省空间。

    最新文章 更多
    最新素材 更多
    公司介绍 网站地图 图片资讯
    Copyright © 2010-2022 山东找图网络科技有限公司  鲁ICP备18007836号-3  邮箱:15653358549@163.com