用ndk实现android的图片压缩

本文介绍了如何使用NDK结合libjpeg库实现Android图片的高效压缩,指出Android原生bitmap.compress方法由于使用了skia库且其采用的不是哈夫曼编码,导致压缩效果不佳。通过引入libjpeg头文件和库,配置CMake,并在Java层声明native方法,实现在JNI层进行图片RGB数据处理和压缩。测试结果显示,采用此方法压缩后的图片大小显著减小,压缩效果优于原生方法。
摘要由CSDN通过智能技术生成

最近在看了动脑学院的图片优化之后,感觉通过ndk来实现的压缩,压缩比例还是很好的

我们知道android的图片显示离不开bitmap,而在android开发中避免不了对图片的压缩处理,当然bitmap有自带的压缩方法,调用bitmap的compress方法就可以实现简单的压缩,但是这种压缩出来的图片从清晰度上来说,效果不是很好,原因在于这种压缩的底层处理是由google的skia图片处理引擎来做的,而skia库又是基于jpeg库,我们都知道libjpeg是一个被广泛使用的JPEG压缩/解压缩函数库,应用程序可以每次从JPEG压缩图像中读取一个或多个扫描线(scanline,所谓扫描线,是指由一行像素点构成的一条图像线条),而诸如颜色空间转换、降采样/增采样、颜色量化之类的工作则都由libjpeg去完成的;但是skia在开发的时候阉割来jpeg的一部分功能,使得android原有的压缩方法不尽人意,下面通过代码来实现一个脱离android 底层的skia库,基于ndk libjpeg压缩的图片压缩方案。

导入相关的依赖库

由于要使用到libjpeg相关的函数,所以要导入相关的头文件与so文件, 由于libjpeg也是在android源码里面的,找到android源码中的/external/libjpeg-turbo/jpeglib.h头文件复制到android studio 的cpp目录下面,当然也可以在cpp下面新建一个include目录将头文件放进去也行,然后将jpeglib.h里面依赖的其他头文件都引入进来,接着就是进入libjpeg.so文件,我这里是将so放在来app目录下的libs目录下面
头文件与so文件目录
当然这个目录不是必须的,放在其他目录也行;然后用cmake将头文件与目录的路径引入就行了;

cmake的配置

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

include_directories( src/main/cpp/ )

add_library(jpeg-and SHARED IMPORTED)
set_target_properties(jpeg-and
  PROPERTIES IMPORTED_LOCATION
  ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libjpeg.so)

find_library(
              log-lib
              log )

#添加jnigraphics,c++代码中使用到了AndroidBitmap,所以需要添加jnigrapics库
find_library(
              andbitmap
              jnigraphics )

add_library(
             native-lib
             SHARED
             src/main/cpp/native-lib.cpp )

target_link_libraries( # Specifies the target library.
                       native-lib
                       ${andbitmap}
                       jpeg-and
                       ${log-lib} )

实现图片压缩

这里我们在java层声明一个native方法

    public native void nativeCompress(Bitmap inputBitmap, String absolutePath);

该方法传入原图的bitmap与输出压缩文件的路径,然后在jni层实现压缩代码

#include <jni.h>
#include <string>
#include <android/bitmap.h>
#include <android/log.h>
#include <malloc.h>

extern "C" {
   
    #include "jpeglib.h"
}

typedef uint8_t BYTE;

void writeImg(BYTE 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值