OpenJPEG开源库
近期老师要求将jpeg2000算法移植到安卓平台上,尝试了很长时间,在这里总结一下经验、
OpenJPEG是Universite catholique de Louvain, Belgium大学的通信和遥感试验室于2003年12月开发出来的。OpenJPEG作为完全用C实现的一款JPEG2000压缩软件,很适合移植到嵌入式平台。
openjpeg库下载
配置NDK环境
点开Android Studio的SDK Manager可以看到上图的界面,选择下载勾选的四个工具。
CMake:允许开发者编写一种平台无关的CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Linux 的 Makefile 或 Windows 的 Visual Studio 工程。
LLDB:一个高效的 C/C++ 的调试工具。
NDK:即编译C/C++源码生成so库的工具,下载后会生成到 SDK 根目录下的ndk-bundle 目录。
配置好NDK环境后,编写CMakeList.txt,可以编译OpenJPEG中图像压缩的代码。
编译openjpeg
我下载的是openjpeg2.0.0版本。在/src/lib/openjp2文件夹下创建一个opj_config.h文件
#ifndef OPJ_CONFIG_H
#define OPJ_CONFIG_H
#define OPJ_PACKAGE_VERSION "2.0.0"
#define HAVE_INTTYPES_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STDINT_H 1
#ifndef HAVE_STDLIB_H // I had a conflict with this somewhere else in my project -- good form dictates that I should probably ifndef guard the other defines in this file as well....that is a TODO for later
#define HAVE_STDLIB_H 1
#endif
#define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_UNISTD_H 1
// I'm not utilizing libpng or libtiff, so don't set these
//#cmakedefine HAVE_LIBPNG @HAVE_LIBPNG@
//#cmakedefine HAVE_PNG_H @HAVE_PNG_H@
//#cmakedefine HAVE_LIBTIFF @HAVE_LIBTIFF@
//#cmakedefine HAVE_TIFF_H @HAVE_TIFF_H@
#define HAVE_SSIZE_T 1
//#cmakedefine _LARGEFILE_SOURCE
//#cmakedefine _LARGE_FILES
//#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@
#define HAVE_FSEEKO 1
//#cmakedefine HAVE_LIBLCMS1
//#cmakedefine HAVE_LIBLCMS2
//#cmakedefine HAVE_LCMS1_H
//#cmakedefine HAVE_LCMS2_H
#endif // OPJ_CONFIG_H
由于这次主要是二维静态图像压缩。所以只编译了OpenJPEG中二维图像压缩模块openjp2和协议交互式工具openjpip以及图像格式转换文件convert。
CMakeLists.txt文件
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${
PROJECT_SOURCE_DIR}/src/main/jniLibs/${
ANDROID_ABI})
include_directories(
${
PROJECT_SOURCE_DIR}/openjpeg/src/lib/openjp2
${
PROJECT_SOURCE_DIR}/openjpeg/src/bin/common
${
PROJECT_SOURCE_DIR}/openjpeg/src/bin/jp2
${
PROJECT_SOURCE_DIR}/openjpeg/src/lib/openjpip
${
PROJECT_SOURCE_DIR}/openjpeg/wrapping/java/openjp2
)
file(GLOB SRC_LIST
//编译src/lib/openjp2文件夹下的所以.c文件
${
PROJECT_SOURCE_DIR}/openjpeg/src/lib/openjp2/.c
//convert.c主要是图片格式转换
${
PROJECT_SOURCE_DIR}/openjpeg/src/bin/jp2/convert.c
//编译src/lib/openjpip文件夹下的所以.c文件
${
PROJECT_SOURCE_DIR}/openjpeg/src/lib/openjpip/.c
//压缩解压缩文件,是封装的jni函数。java层调用这两个文件完成压缩解压缩
${
PROJECT_SOURCE_DIR}/openjpeg/wrapping/java/openjp2/compress.c
${
PROJECT_SOURCE_DIR}/openjpeg/wrapping/java/openjp2/decompress.c
)
#aux_source_directory(${PROJECT_SOURCE_DIR}/openjpeg-2.3.1/src/lib/openjp2 ${PROJECT_SOURCE_DIR}/openjpeg-2.3.1/src/lib/openjpip SRC_LIST)
add_definitions(-DUSE_JPIP)
add_library( # Sets the name of the library.
openjpeg-lib
SHARED //动态库
${
SRC_LIST})
find_library( # Sets the name of the path variable.
log-lib
log)
target_link_libraries( # Specifies the target library.
openjpeg-lib
${
log-lib})
build.gradle文件
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.openjpeg"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
//path "src/main/cpp/openjpeg/wrapping/java/openjp2/CMakeLists.txt"
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
sourceSets {
main {
jniLibs.srcDirs = [ ]
// jniLibs.srcDirs = ['src/main/jniLibs/']
//jni.srcDirs = ['src/main/jni', 'src/main/jni/']
} }
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation project(path: ':openCVLibrary330')
}
自己编写java接口
压缩接口
package com.example.openjpeg;
public class Encoder {
static {
System.loadLibrary("openjpeg-lib");
}
public int encoderImageToJ2K(String inputImagepath,
String outputJ2kpath,
int ratio,
boolean isgrayBmp)
{
return internalEncodeImageToJ2K( inputImagepath, outputJ2kpath, ratio, isgrayBmp);
}
//JNI接口函数,对图像进行压缩编码,四个参数,
// 第一个参数是输入的bmp图片路径,
// 第二个参数是输出的j2k格式图片路径
// 第三个参数是设置压缩比
// 第四个参数是输入的压缩图片是否是灰度图
public native int internalEncodeImageToJ2K(String inputImagepath,
String outputJ2kpath,
int ratio,
boolean isgrayBmp);