手把手教你生成自己的图片压缩的so库

简介:        最近安卓开发里面最火的是什么?NDK开发啊,之前面试的时候好几家公司都问我会不会这个,或者直接就出了这样类型的笔试题,当时的我也是一脸懵逼。

       最近安卓开发里面最火的是什么?NDK开发啊,之前面试的时候好几家公司都问我会不会这个,或者直接就出了这样类型的笔试题,当时的我也是一脸懵逼。恰好这段时间研究了图片压缩和视频压缩的NDK开发,话不多说,开干吧!

      以往的图片压缩大家都知道无非是进行图片质量压缩和按比例压缩,但是这样不靠谱啊,压缩严重点直接就趋于马赛克(可能有点夸张)了,好伐。于是libjpeg就登场了,具体为啥,我就不说了,请看上一篇的英文介绍,而且网上一大片相同的原因介绍。今天我主要讲的是生成自己的libjpeg.so库:

     

     一、安装NDK(硬件环境:Win10 x86, 开发工具:Android Studio)

     打开android Studio的Project Structure,在Android NDK Location 填入你的NDK路径,比如我的是——D:\Android\sdk\ndk-bundle。如果你的电脑里面没有下载NDK,那应该有个Download的按钮,直接下载最新的NDK即可。

     打开环境变量,在系统变量里面新增“NDK_ROOT”,把你的NDK路径填进去,然后保存之后在用户变量为“Path”的变量里面增加“%NDK_ROOT%。

      检查NDK是否安装成功,成功的提示如下图:

      

     失败的话就会提示“ndk-build不是内部命令”。

      二、编译过程

      1、新建一个Android Project,去https://github.com/Dm47021/libjpeg-turbo把libjpeg-turbo下载下来,解压缩后把“libjpeg-turbo-android”的文件名改为“jni”,扔进我们的app目录下,如下图所示:


      2、打开cmd,cd到这个jni目录,输入命令“ndk-build”,如下图所示(E:MyJpgCompress\app\jni是我的jni文件路径),本来应该一切顺利地进行,然而你会发现报一大片了,错误如下:


很显然报错的地方在jdcolor-armv7.S,而且我发现几乎每行代码都不被支持。于是我开始查看jni目录下的Android.mk文件,也就是makefile配置文件,帮我们把C/C++的代码编译成动态库so的一个文件。里面的代码表明libjpeg.so库的生成是需要用到libsimd的,也就是下面的这行代码,而且正是这个libsimd的编译需要用到报错的那个文件,这下可怎么办呢?

只好在网上寻求帮助了,好在功夫不负有心人,有人已经在github上把这个图片压缩的一些东西抽离了出来,事情变得简单起来。附上网址:https://github.com/bither/bither-android-lib。

我把这个项目下载了下来,把他用到的libjpeg-turbo-android和我的一对比,果然少了asm文件夹,并且在Android.mk中把

asm/armv7//jdcolor-armv7.S asm/armv7/jdidct-armv7.S \
这一行去掉了。干脆把jni下的asm文件夹删除,并且换成他的Android.mk,再ndk-build一下,libjpegbither.so生成了,当然如果你想给这个库换个名称也是可以的,直接在Android.mk中查找“libjpegbither”并全部修改成你要的名称即可,因为这个名称基本都是这样的,而LOCAL_SHARED_LIBRARIES就是指我们要生成一个或多个的静态库。

LOCAL_SHARED_LIBRARIES := libjpegbither

这里为了方便,我就直接在他的项目上进行编译了,这个具体的其实可以根据路径E:\bither-android-lib-master\libjpeg-turbo-android\use-libjpeg-turbo-android\jni下的README.md这个文件进行编译。当然了,既然我说要手把手教,那还是继续下面的图解编译过程。

第一步:进入jni路径下,输入命令行ndk-build进行编译,当然你也可以加上“APP_ABI=armeabi-v7a,armeabi”,这样就可以编译出这个so库的多个版本。


编译完成后在这个项目下的libs文件夹会生成相应的文件夹armeabi和armeabi-v7a,里面分别有一个我们需要的“libjpegbither.so”的文件。


第二步:

把这两个生成的文件夹文件放入“use-libjpeg-turbo-android”的jni文件夹下,cd到这个jni文件夹下,输入ndk-build命令进行编译,不过我运行到这里的时候却报错了,错误如下:

E:\bither-android-lib-master\libjpeg-turbo-android\use-libjpeg-turbo-android\jni>ndk-build APP_ABI=armeabi-v7a,armeabi
[armeabi-v7a] Compile thumb  : bitherjni <= bitherlibjni.c
E:/bither-android-lib-master/libjpeg-turbo-android/use-libjpeg-turbo-android//jni/bitherlibjni.c:18:28: fatal error: and
roid/bitmap.h: No such file or directory
 #include <android/bitmap.h>

这个该怎么办呢?我查阅了资料后找到了解决方法,请查看网址https://stackoverflow.com/questions/11656833/android-ndk-wont-build-library-because-bitmap-h-is-missing中的解答,最终我通过下面这个命令行编译出了自己想要的so库——libbitherjni.so和libjpegbither.so。

ndk-build APP_PLATFORM=android-8

把生成的so库放进我们需要用到的工程里面,对应新建相关的包名类名和方法名,也就是net.bither.util包下的NativeUtil类中的compressBitmap方法,参数也一定要对应上。

在NativeUtil类中加上下面的引用,然后我们就可以调用相应的图片压缩方法了。

static {
    System.loadLibrary("bitherjni");
    System.loadLibrary("jpegbither");
}
 

因为是要生成自己的so库,很多时候大家的项目包名甚至图片压缩工具类名都已经是确定的了,不愿意再加上上面这个包名,这时候只需要在第二步的时候,把jni路径下名为“bitherlibjni.c”的文件中代码进行小小的修改,重新编译即可。

在这个文件中请找到如下图的一段代码:


其中net_bither_util就对应着包名net.bither.util,NativeUtil对应着工具类名,compressBitmap对应着方法名,可以根据个人的需要进行修改,比如我的包名是com.sherry.jpegcompress,在ImageUtil工具类中调用方法compressBtp进行图片压缩,那就可以直接把上面这个方法改为com_sherry_jpegcompress_ImageUtil_compressBtp,然后再进行ndk-build的操作。


好的,我的图片压缩生成相关so库的教程到这里就结束了,后续会附上自己图片压缩相关的全部代码和对应打包成功的so库。如果大家图方便可以直接修改上面那个包名和方法名,然后在项目里面使用,不过还是建议大家自己玩一遍。



目录
相关文章
|
7月前
|
Ubuntu
音视频ubuntu安装ffmpeg6.0简略笔记
音视频ubuntu安装ffmpeg6.0简略笔记
176 0
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
97 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
6月前
|
编解码 Linux
FFmpeg开发笔记(二十八)Linux环境给FFmpeg集成libxvid
XviD是开源的MPEG-4视频编解码器,曾与DivX一起用于早期MP4视频编码,但现在已被H.264取代。要集成XviD到Linux上的FFmpeg,首先下载源码,解压后配置并编译安装libxvid。接着,在FFmpeg源码目录中,重新配置FFmpeg以启用libxvid,然后编译并安装。成功后,通过`ffmpeg -version`检查是否启用libxvid。详细步骤包括下载、解压libxvid,使用`configure`和`make`命令安装,以及更新FFmpeg配置并安装。
95 2
FFmpeg开发笔记(二十八)Linux环境给FFmpeg集成libxvid
|
7月前
|
编解码 并行计算 JavaScript
Nodejs 第十六章(ffmpeg)
Nodejs 第十六章(ffmpeg)
161 0
|
7月前
|
编解码 搜索推荐 开发者
FFmpeg开发笔记(三)FFmpeg的可执行程序介绍
FFmpeg提供ffmpeg、ffplay和ffprobe三个可执行程序。ffmpeg用于音视频转换和查询支持信息,如编解码器、文件格式和协议。ffplay是一个简单的播放器,支持播放音视频并显示相关信息。ffprobe用于分析多媒体文件参数和数据包详情。《FFmpeg开发实战:从零基础到短视频上线》一书提供更深入的开发知识。
81 4
FFmpeg开发笔记(三)FFmpeg的可执行程序介绍
|
7月前
|
存储 编解码 缓存
FFmpeg之旅:深入解析FFplay源码
FFmpeg之旅:深入解析FFplay源码
632 0
|
7月前
|
编解码 索引 Windows
FFMPEG常用指令整理(未完结)
ffmpeg是通用的媒体转换器,可以将广泛的输入(包括实时的抓取和记录设备)-过滤和转换为我们想要的输出格式文件。
127 0
|
7月前
【音视频 ffmpeg 学习】 跑示例程序 持续更新中
【音视频 ffmpeg 学习】 跑示例程序 持续更新中
|
7月前
|
存储 编解码 算法
ffmpeg笔记(一)音视频基础
ffmpeg笔记(一)音视频基础
175 0
|
7月前
|
Linux API C++
音视频windows安装ffmpeg6.0并使用vs调试源码笔记
音视频windows安装ffmpeg6.0并使用vs调试源码笔记
243 0