性能优化--哈夫曼算法原理

大家都知道,使用哈夫曼压缩能达到无损压缩,也就是说。保证了原图质量的同时,能够降低图片的大小。这是什么原理呢?首先我们需要了解的是Android系统加载图片使用的是Skia加载库,当然这个库的底层还是是用的jpeg对图片进行压缩处理,但是为了能够适配低端的手机(这里的低端是指以前的硬件配置不高的手机,CPU和内存在手机上都非常吃紧 性能差),由于哈夫曼算法非常吃CPU,被迫用了其他的算法。所以Skia在进行图片处理并没有去使用到哈夫曼压缩。但是解码还是保留了哈夫曼算法,这就导致了图片处理后文件变大了。

一、原理

看一张图,如下:
在这里插入图片描述
这里解释一下,一张图片都是有argb组成,这经过哈夫曼压缩之前,可以将图片的a通道拿掉,剩下的 rgb 进行压缩。每一个通道的取值范围都是0~255,也就是说每种颜色都是有256种表现形态,这里以红色 r 为例。假如一张图片红色 r 共有6个等级,每个等级对应的像素点数如上图。那么根据哈夫曼算法会形成一个哈夫曼树。如下图:
在这里插入图片描述
哈夫曼树形成的规则,首先从6个等级中找出两个像素点最少的两个(1和10),放在末端,然后将两个像素点相加放在左端,然后再找出原像素点中较少的一个(100),放在右端,并用线将节点和分支连接起来。依次类推,直到找到顶点。其中左边的分支用0标记,右边的分支用1标记。

1个rgb对应3个字节,每一个字节都会形成一个像素表,像素表中存储每个像素等级对应的像素点数。比如根据哈夫曼树,我们如何找到红色的等级1的像素,我们从顶点出发,只需要在表中查找1,就可以找到5000,那么如何找到1000呢?查找01!如何查找500呢?查找001!如何查找100呢?0001?…等等。就是根据分支一直找下去。

优点:对于原始一个像素点占8位,对于5000个像素点,所有那个内存为8*5000 ,当使用哈夫曼压缩后,只要一位(比如1)就可以表示这5000个像素点。并且没有减少图片的像素点数,所以叫做无损压缩。另外,对于颜色值越单一的图片,压缩率越高。颜色值越多,树会越来越长,找到末端的像素点占用的位数会越来越多。所以它的压缩效率一般在20%~90%。

二、实现

1、导库

这里我们需要libjpeg在android环境下的so库,所以需要事先在linux环境下编译好。将编译好的so库放到项目中,如下:
在这里插入图片描述
其中x86支持的模拟器,arm64真机。导入需要支持的头文件在libjpeg目录下:
在这里插入图片描述

2、链接库

需要在CMakeList.txt文件中配置,如下;
在这里插入图片描述
红色框框的内容,就是需要添加的。

3、调用
/**
     * @param bitmap 要压缩的图片
     * @param path 压缩后存放的文件名称
     * @param quality 压缩质量
     */
    public native void compressImage(Bitmap bitmap, String path, int quality);

    public void compress(View view) {
   

        //sd卡目录下的一张图片
        File input = new File(Environment.getExternalStorageDirectory(), "timg750.png");
        inputBitmap = BitmapFactory.decodeFile(input.getAbsolutePath());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值