android cmake 打印_Android使用CMAKE编译libjpeg
本文主要介紹使用 CMAKE 編譯 libjpeg-turbo 類庫,本文相關(guān)代碼請?jiān)贕itHub-TurboJpegSample 查看。
libjpeg-turbo 附GitHub 地址,libjpeg-turbo 是個(gè)運(yùn)用極其廣泛的庫,可以說,基本上電腦上手機(jī)上能見到的 JPEG 壓縮的地方用的一般都是 libjpeg-turbo,本文只介紹使用了圖片壓縮的功能。
使用 Android 保存圖片時(shí),我們通常使用的是 Bitmap.compress() 方法,但是使用該方法時(shí),就算 quality 設(shè)置為 100,圖片質(zhì)量還是會(huì)越來越模糊,顏色也會(huì)越來越綠~,至于為什么會(huì)這樣,請看 知乎回答。 這個(gè)問題在貼吧上體現(xiàn)尤為明顯,貼吧里面經(jīng)常很多綠綠的圖片就是因?yàn)榇蠹冶4嫦聛砩蟼魃先?#xff0c;保存下來上傳上去 … 導(dǎo)致質(zhì)量越拉越低,我解壓了 美圖秀秀 和 in 的 apk 發(fā)現(xiàn)里面都引用了 libjpeg.so,所以這個(gè)應(yīng)該是一個(gè)比較通用的解決方案。
我們對圖片使用質(zhì)量壓縮時(shí)它的底層就是用 skia 引擎進(jìn)行處理,如我們調(diào)用bitmap.compress(Bitmap.CompressFormat.JPEG...) 他實(shí)際會(huì) 使用一個(gè)libjpeg.so 的動(dòng)態(tài)庫進(jìn)行編碼壓縮。android 在進(jìn)行 jpeg 壓縮編碼的時(shí)候,考慮到了效率問題使用了定長編碼方式進(jìn)行編碼(因?yàn)楫?dāng)時(shí)的手機(jī)性能都比較低),而 ios 使用了變長編碼的算法——哈夫曼算法。而且 IOS 對 skia 引擎也做了優(yōu)化,所以我們看到同樣的圖片在 ios 上壓縮會(huì)好一點(diǎn)。
文檔就整理到這里吧,其實(shí)上面說的都是看了一些博客的介紹然后進(jìn)行了整理和記錄,來清楚為什么我們需要自己來編譯 so 實(shí)現(xiàn)圖片壓縮。
資源準(zhǔn)備
我們需要下載源碼編譯出 libjpeg.so 來使用,clone 源代碼。1git clone git://git.linaro.org/people/tomgall/libjpeg-turbo/libjpeg-turbo.git -b linaro-android
重命名根目錄 libjpeg-turbo 為 jni,進(jìn)入 jni 目錄,首先你應(yīng)該配置好 ndk, 使用 ndk-build 命令進(jìn)行編譯。1
2
3
4mv libjpeg-turbo jni
ndk-build APP_ABI=armeabi-v7a,armeabi
編譯完成之后我們就可以獲取到 libjpeg.so,目錄如下:1
2
3
4
5
6
7
8
9
10jni
libs
- armeabi
- libjpeg.so
- armeabi-v7a
- libjpeg.so
obj
- local
- armeabi
- armeabi-v7a
此時(shí)如果出現(xiàn)了以下異常:1
2Users/march/AndroidRes/sdk/ndk-bundle/build/core/build-binary.mk:702:
*** Android NDK: Aborting (set APP_ALLOW_MISSING_DEPS=true to allow missing dependencies) . Stop.
打開 build-binary.mk 添加 APP_ALLOW_MISSING_DEPS=true1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18ifdef undefined_libs
$(call __ndk_warning,Module $(LOCAL_MODULE) depends on undefined modules: $(undefined_libs))
# ndk-build didn't used to fail the build for a missing dependency. This
# seems to have always been the behavior, so there's a good chance that
# there are builds out there that depend on this behavior (as of right now,
# anything using libc++ on ARM has this problem because of libunwind).
#
# By default we will abort in this situation because this is so completely
# broken. A user may define APP_ALLOW_MISSING_DEPS to "true" in their
# Application.mk or on the command line to revert to the old, broken
# behavior.
APP_ALLOW_MISSING_DEPS=true # here
ifneq ($(APP_ALLOW_MISSING_DEPS),true)
$(call __ndk_error,Aborting (set APP_ALLOW_MISSING_DEPS=true to allow missing dependencies))
endif
endif
創(chuàng)建工程
使用 AndroidStudio 新建工程,勾選 support c++,生成的工程中會(huì)包含 CMakeLists.txt 文件,在下面的介紹中沒有截圖,對目錄的說明如果不夠清晰,請至 GitHub-TurboJpegSample 查看工程代碼。
在 app 目錄下新建文件夾 libjpeg,用來存放 so 文件和頭文件,目錄如下:1
2
3
4
5
6
7
8
9
10
11
12app
- libjpeg
- prebuilt
- armeabi
- libjpeg.so
- include
- 頭文件
- src
- main
- cpp
- java
- res
編寫 compress.h 和 compress.c,這個(gè)就是壓縮的核心代碼了,篇幅較長,但是這里就不貼了,詳情請查看 項(xiàng)目的 cpp 目錄,使用的算法是網(wǎng)上查找的,看起來資料介紹的都是這一種。
CMakeLists.txt1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31# 最低版本
cmake_minimum_required(VERSION 3.4.1)
#設(shè)置生成的 so 動(dòng)態(tài)庫最后輸出的路徑
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
# 初始化目錄變量
set(libjpeg_dir ${CMAKE_SOURCE_DIR}/libjpeg)
set(INC_DIR ${libjpeg_dir}/include)
set(libjpeg_lib_dir ${libjpeg_dir}/prebuilt)
# 添加頭文件目錄
include_directories(${INC_DIR})
# 設(shè)置資源路徑
set(SOURCE_FILES src/main/cpp/compress.c)
#
add_library(compress SHARED
${SOURCE_FILES})
find_library(log-lib log)
find_library(graphics jnigraphics)
add_library(libjpeg SHARED IMPORTED)
set_target_properties(libjpeg PROPERTIES IMPORTED_LOCATION ${libjpeg_lib_dir}/${ANDROID_ABI}/libjpeg.so)
target_link_libraries(compress libjpeg ${log-lib} ${graphics})
build.gradle
相比普通的 Android 工程,app/build.gradle 文件也有些許不同,我只編譯了 armeabi 。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
...
externalNativeBuild {
cmake {
abiFilters 'armeabi'
}
}
ndk {
//打包進(jìn)APK的ABI類型
abiFilters 'armeabi'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
java.srcDirs 'src/java'
jniLibs.srcDirs 'libs'
// jniLibs.srcDirs '../libjpeg/prebuilt', 'libs'
// 這里沒有添加libjpeg.so這個(gè)動(dòng)態(tài)庫,也是可以執(zhí)行的。
// 原因在于android本身使用了 libjpeg.so這個(gè)動(dòng)態(tài)庫,
// 這個(gè)庫存放在/system/lib下,如果我們沒有加入
// libjpeg.so的話,他會(huì)去/system/lib下加載這個(gè)動(dòng)態(tài)庫
// 如果android手機(jī)上沒有 libjpeg.so這個(gè)動(dòng)態(tài)庫的話,
// 也可以使用: jniLibs.srcDirs '../libjpeg/prebuilt' 'libcd
// 將libjpeg.so加入到apk中
}
}
}
編寫 java 調(diào)用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class{
static {
System.loadLibrary("compress");
}
/**
* 使用native方法進(jìn)行圖片壓縮。
* Bitmap的格式必須是ARGB_8888 {@link android.graphics.Bitmap.Config}。
*
* @param bitmap 圖片數(shù)據(jù)
* @param quality 壓縮質(zhì)量
* @param dstFile 壓縮后存放的路徑
* @param optimize 是否使用哈夫曼算法
* @return 結(jié)果
*/
public static native int compress(Bitmap bitmap, int quality, String dstFile, boolean optimize);
}
運(yùn)行之后就可以測試結(jié)果,同時(shí)在 配置的 jniLibs 目錄中也會(huì)生成 so 文件,在別的地方使用同包名下的 TurboJpegUtils 類也可以調(diào)用了。
總結(jié)
測試對比結(jié)果,確實(shí)比 Andorid 原生的算法壓縮圖片的效果好很多,但是壓縮次數(shù)多了以后也會(huì)有明顯的模糊現(xiàn)象。
總結(jié)
以上是生活随笔為你收集整理的android cmake 打印_Android使用CMAKE编译libjpeg的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 本周发 小米新一代神机预定:神U天玑81
- 下一篇: 正则表达式: input框禁止输入空格: