最近在看了动脑学院的图片优化之后,感觉通过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目录下面
当然这个目录不是必须的,放在其他目录也行;然后用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