android cmake 打印_Android使用CMAKE编译libjpeg

本文主要介绍使用 CMAKE 编译 libjpeg-turbo 类库,本文相关代码请在GitHub-TurboJpegSample 查看。

libjpeg-turbo 附GitHub 地址,libjpeg-turbo 是个运用极其广泛的库,可以说,基本上电脑上手机上能见到的 JPEG 压缩的地方用的一般都是 libjpeg-turbo,本文只介绍使用了图片压缩的功能。

使用 Android 保存图片时,我们通常使用的是 Bitmap.compress() 方法,但是使用该方法时,就算 quality 设置为 100,图片质量还是会越来越模糊,颜色也会越来越绿~,至于为什么会这样,请看 知乎回答。 这个问题在贴吧上体现尤为明显,贴吧里面经常很多绿绿的图片就是因为大家保存下来上传上去,保存下来上传上去 … 导致质量越拉越低,我解压了 美图秀秀 和 in 的 apk 发现里面都引用了 libjpeg.so,所以这个应该是一个比较通用的解决方案。

我们对图片使用质量压缩时它的底层就是用 skia 引擎进行处理,如我们调用bitmap.compress(Bitmap.CompressFormat.JPEG...) 他实际会 使用一个libjpeg.so 的动态库进行编码压缩。android 在进行 jpeg 压缩编码的时候,考虑到了效率问题使用了定长编码方式进行编码(因为当时的手机性能都比较低),而 ios 使用了变长编码的算法——哈夫曼算法。而且 IOS 对 skia 引擎也做了优化,所以我们看到同样的图片在 ios 上压缩会好一点。

文档就整理到这里吧,其实上面说的都是看了一些博客的介绍然后进行了整理和记录,来清楚为什么我们需要自己来编译 so 实现图片压缩。

资源准备

我们需要下载源码编译出 libjpeg.so 来使用,clone 源代码。1git clone git://git.linaro.org/people/tomgall/libjpeg-turbo/libjpeg-turbo.git -b linaro-android

重命名根目录 libjpeg-turbo 为 jni,进入 jni 目录,首先你应该配置好 ndk, 使用 ndk-build 命令进行编译。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

此时如果出现了以下异常: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

创建工程

使用 AndroidStudio 新建工程,勾选 support c++,生成的工程中会包含 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,这个就是压缩的核心代码了,篇幅较长,但是这里就不贴了,详情请查看 项目的 cpp 目录,使用的算法是网上查找的,看起来资料介绍的都是这一种。

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)

#设置生成的 so 动态库最后输出的路径

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})

# 设置资源路径

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 {

//打包进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这个动态库,也是可以执行的。

// 原因在于android本身使用了 libjpeg.so这个动态库,

// 这个库存放在/system/lib下,如果我们没有加入

// libjpeg.so的话,他会去/system/lib下加载这个动态库

// 如果android手机上没有 libjpeg.so这个动态库的话,

// 也可以使用: jniLibs.srcDirs '../libjpeg/prebuilt' 'libcd

// 将libjpeg.so加入到apk中

}

}

}

编写 java 调用1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18public class{

static {

System.loadLibrary("compress");

}

/**

* 使用native方法进行图片压缩。

* Bitmap的格式必须是ARGB_8888 {@link android.graphics.Bitmap.Config}。

*

* @param bitmap 图片数据

* @param quality 压缩质量

* @param dstFile 压缩后存放的路径

* @param optimize 是否使用哈夫曼算法

* @return 结果

*/

public static native int compress(Bitmap bitmap, int quality, String dstFile, boolean optimize);

}

运行之后就可以测试结果,同时在 配置的 jniLibs 目录中也会生成 so 文件,在别的地方使用同包名下的 TurboJpegUtils 类也可以调用了。

总结

测试对比结果,确实比 Andorid 原生的算法压缩图片的效果好很多,但是压缩次数多了以后也会有明显的模糊现象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式(四)结构型模式

前言 结构型设计模式,主要研究: 主要有哪些场景使用结构型设计模式;每种场景应该使用何种设计模式;以程序中的功能为核心,研究程序功能的组织结构。所以这一章,我们要把“功能结构”作为研究的核心。 下…

centos 删除crontab_centos下crontab的使用

4.cron文件语法:分 小时 日 月 星期 命令0-59 0-23 1-31 1-12 0-6 command (取值范围,0表示周日一般一行对应一个任务)5.记住几个特殊符号的含义:“*”代表取值范围内的数字,“/”代表”每”,“-”代表从某个数字到某个数字,“,”分开…

【转】GitHub客户端操作1--仓库相关操作github团队协作流程

1、创建仓库 点击“”,点击Create,然后填写Name为my,点击Create repository,即可创建一个my仓库 2、从本地仓库存放位置,添加test仓库到GitHub客户端 点击“”,点击Add,然后点击Browse,选择仓库存放位置&a…

音视频相关链接

开发库 FFmpeg FFmpeg官网 FFmpeg github 平台相关 DirectShow DirectShow简介 DirectShow官网

【转】GitHub客户端操作2--分支操作

简单分支操作 (1)创建新分支:my分支 备注:新创建的分支:my分支里面的内容是和master分支里面的内容是完全一样的。 (2)删除my分支 (3)修改my分支【在my分支上进行项目内…

uniapp动态修改样式_uniapp样式动态绑定

场景一:用户点击按钮后动态切换按钮选中样式(如图)已上线未开始//选择状态selectState(e){this.whichSelectede.currentTarget.dataset.state}.state-btn-content{//write your style.state-btn-selected{ ... }.state-btn-noselect{ ... }}注:需要注意的…

音视频工程师(初步)(一)音视频的基本概念

1. 前言 本文是音视频工程师系列的第一篇文章。 学习音视频的过程中发现,网络上高质量的音视频技术博客不是很多。具有代表性的是 雷神的 雷霄骅的CSDN博客 因为笔者是一名普通的软件开发人员,一向不喜欢高高在上或者晦涩难懂的理论,我们…

【转】GitHub客户端操作3--pull Request(拉请求)

一、参考说明 参考文章一:Github上提交代码(pullrequest) 网址: https://jingyan.baidu.com/article/358570f64dcdc2ce4724fc32.html 参考文章二:GitHub——Pull Request 网址:http://blog.csdn.net/u012325167/article/detai…

webstorm 内存溢出怎么弄_webstrom 内存溢出,软件崩溃卡死解决的方法

今天用gulp搭建了一个工程,准备做一个体育h5的项目,其中需要用到sass代码压缩,加版本号等功能.gulpfile.js和package.json都是已经写好的.我用CMD命令窗口cnpm安装node_modules依赖文件.当我安装完毕之后用webstrom打开时,第一件事先把node_modules排除忽略了.如下:然后我去编辑…

躺平也要看,2022年计算机相关考试汇总

1. 全国计算机专业资格考试(软考) 1.1 官网 全国官网:https://www.ruankao.org.cn/,从全国官网首页的底部可以直达各个省区的考试机构报名网站。 1.2 考试安排 软考一年两次。 场次报名时间考试时间上半年 预计报名时间在2月…

【转】GitHub上README.md教程

本文是转载文章,文章的来源:csdn博客 博主:果冻虾仁 文章: GitHub上README写法暨GFM语法解读 博文地址:https://blog.csdn.net/guodongxiaren/article/details/23690801 转载请保留原作者guodongxiaren的原文地址&…

python supervisor flask_supervisor配合uwsgi部署flask应用

这已经是第N次来部署flask应用了, 但是每次都花了不少时间在配置上面, 这里一次性记录下, 备个忘~写在前面其实使用uwsgi来部署flask应用在官网上已经有较为详细的 文档 了, 推荐先读一下.先解决一些问题:为何使用 uwsgi 来部署应用? 方便管理; 较为常见的部署方式; 可配置性较…

设计模式(五)行为型模式

前言 在上一篇结构型模式中,我们以功能为基本单位,研究了一些设计模式,用于实现功能转换、功能组合、功能封装等目的。 我们知道,面向对象编程有两个核心元素:对象、对象间通信协作。从面向对象的角度看,…

51单片机auxr寄存器_51—52系列单片机特殊功能寄存器一览表

P2.1P2.0RSTP3.0/RXDP3.1/TXDXTAL2XTAL1P3.2/INT0P3.3/INT1P3.4/T0P3.5/T1GNDVCCP1.7P1.6P1.5P1.4P1.3P1.2P1.1/AIN1P1.0/AIN0P3.7注:类似的还有Philips公司的87LPC64,20引脚8XC748/750/(751),24引脚8X749(752),28引脚8XC754&…

【转】WPF单位真的与分辨率无关吗?

转载自http://www.cnblogs.com/helloj2ee/archive/2009/04/21/1440709.htm WPF从发布之日起,一直将“分辨率无关(resolution independence)”作为其亮点,声称使用WPF制作的用户界面在轻巧的Ultra-Mobile PC的屏幕上和在50英寸的电视机上都能很好地显示。…

设计模式(六)J2EE 模式

前言 本章设计模式只挑了一些必要的加以讲解,因为有的设计模式过于简单或者根本用不到,可以不做了解。 MVC 模式 使用说明 MVC模式可以说是最有名的设计模式之一。它提出将软件的数据模型Model、视图Visual、控制器Controller三者分开封装&#xff0c…

ubuntu设置始终亮屏_ubuntu设置关闭屏幕和锁定

见链接:http://askubuntu.com/questions/177348/how-do-i-disable-the-screensaver-lockIf you want to wrap your app in a script that takes care of this for you when you launch it (or GUI simply isnt an option), the best command-line solution as of Ub…

【转】世上最简单的vue教程

一、需要了解的基本知识 node.js Node.js是一个Javascript运行环境(runtime),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装。Node.js对一些特殊用例进行优化,提供替代的API,使得V8在非浏览器环境…

工程师学乐理(一)尝试理解音乐

前言 很早就接触了乐理,但是一直没有学懂,越学问题越多。个人感觉,其中很大的原因是有关教材写得看不懂,用未知的东西描述未知的东西,不知所云。前几年还买了一把吉他,买了课程,断断续续学了几…

【转】Vue.js入门教程(一)从静态页面到前后端分离开发

第一章:基础知识 我能看懂吗? 只要你现在能用htmlcssjs制作一个静态页面,相信我,你100%可以读懂这篇文章。 本文尤其适合那些想要了解前后端分离开发技术,或者刚刚脱离传统MVC开发模式的前端人员。 回想一下&#xf…