NDK开发(八) :JNI下Bitmap的使用
开发 使用 ndk bitmap JNI
2023-06-13 09:16:00 时间
转载请以链接形式标明出处: 本文出自:103style的博客
本文操作以 Android Studio 3.4.2 版本为例
- NDK开发(一) :NDK入门指南
- NDK开发(二) :JNI的数据类型
- NDK开发(三) :JNI访问Java变量和方法
- NDK开发(四) :JNI操作Java数组
- NDK开发(五) :JNI实现文件加解密
- NDK开发(六) :JNI实现文件拆分和合并
- NDK开发(七) :JNI实现文件夹遍历
- NDK开发(八) :JNI下Bitmap的使用
目录
- NDK 中的 Bitmap
- 编写测试代码
- 实现JNI下Bitmap使用的逻辑
- 执行测试代码
NDK 中的 Bitmap
NDK
已经为我们准备好了操作 Bitmap
的相关头文件了,它就是 <android/bitmap.h>
。
像素格式
enum AndroidBitmapFormat {
ANDROID_BITMAP_FORMAT_NONE = 0,
ANDROID_BITMAP_FORMAT_RGBA_8888 = 1,
ANDROID_BITMAP_FORMAT_RGB_565 = 4,
ANDROID_BITMAP_FORMAT_RGBA_4444 = 7,
ANDROID_BITMAP_FORMAT_A_8 = 8,
};
Bitmap
结构体,通过AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap, AndroidBitmapInfo* info)
获取。
typedef struct {
//像素宽度
uint32_t width;
//像素高度
uint32_t height;
//每一行占几个字节
uint32_t stride;
//像素格式
int32_t format;
/** Unused. */
uint32_t flags; // 0 for now
} AndroidBitmapInfo;
提供的方法
//获取bitmap的图片信息
int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
AndroidBitmapInfo* info);
//获取像素信息
int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr);
//释放像素信息
int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap);
调用函数返回码
enum {
//调用成功
ANDROID_BITMAP_RESULT_SUCCESS = 0,
//参数错误
ANDROID_BITMAP_RESULT_BAD_PARAMETER = -1,
//出现异常
ANDROID_BITMAP_RESULT_JNI_EXCEPTION = -2,
//分配失败
ANDROID_BITMAP_RESULT_ALLOCATION_FAILED = -3,
};
编写测试代码
创建类 JniBitmapDemo,编写对应的测试代码:
public class JniBitmapDemo {
private static final String TAG = "JniBitmapDemo";
static {
System.loadLibrary("bitmap");
}
public native void passBitmap(Bitmap bitmap);
public void test() {
Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
bitmap.eraseColor(0xff336699); // AARRGGBB
byte[] bytes = new byte[bitmap.getWidth() * bitmap.getHeight() * 4];
Buffer dst = ByteBuffer.wrap(bytes);
bitmap.copyPixelsToBuffer(dst);
// ARGB_8888 真实的存储顺序是 R-G-B-A
Log.d(TAG, "R: " + Integer.toHexString(bytes[0] & 0xff));
Log.d(TAG, "G: " + Integer.toHexString(bytes[1] & 0xff));
Log.d(TAG, "B: " + Integer.toHexString(bytes[2] & 0xff));
Log.d(TAG, "A: " + Integer.toHexString(bytes[3] & 0xff));
passBitmap(bitmap);
}
}
创建bitmap.cpp
.
添加以下代码到CMakeLists.txt
:
add_library(
bitmap
SHARED
bitmap.cpp)
target_link_libraries(
bitmap
jnigraphics
${log-lib})
实现JNI下Bitmap使用的逻辑
#include <jni.h>
#include <android/bitmap.h>
#include <android/log.h>
#include <cstring>
#include "LogUtils.h"
extern "C"
JNIEXPORT void JNICALL
Java_com_lxk_ndkdemo_JniBitmapDemo_passBitmap(JNIEnv *env, jobject instance, jobject bitmap) {
if (nullptr == bitmap) {
LOGE("bitmap is null");
}
AndroidBitmapInfo info;
int result;
//获取图片信息
result = AndroidBitmap_getInfo(env, bitmap, &info);
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
LOGE("AndroidBitmap_getInfo failed, result: %d", result);
return;
}
LOGD("bitmap width: %d, height: %d, format: %d, stride: %d", info.width, info.height,
info.format, info.stride);
unsigned char *addrPtr;
// 获取像素信息
result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void **>(&addrPtr));
if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
LOGE("AndroidBitmap_lockPixels failed, result: %d", result);
return;
}
// 执行图片操作的逻辑
int length = info.stride * info.height;
for (int i = 0; i < length; ++i) {
LOGD("value: %x", addrPtr[i]);
}
// 像素信息不再使用后需要解除锁定
result = AndroidBitmap_unlockPixels(env, bitmap);
if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
LOGE("AndroidBitmap_unlockPixels failed, result: %d", result);
}
}
执行测试代码
new JniBitmapDemo().test();
会在控制台打印Bitmap
对应的信息。
如果出现undefined reference to AndroidBitmap_getInfo
类似的报错信息。
是因为CMakeLists.txt
中没有添加jnigraphics
.
target_link_libraries(
bitmap
jnigraphics
${log-lib})
Demo地址:https://github.com/103style/NDKDoc/tree/master/NDKDemo
以上
相关文章
- 使用python的Django库开发一个简单的数据可视化网站(一)- 基本环境安装及配置
- 使用 rhai、handlebars、graphql 开发 Rust web 前端(3)- rhai 脚本、资源文件、环境变量等
- Java开发中BASE64Encoder的使用
- iOS开发-用户定位获取-CoreLocation的实际应用-CLLocationManger获取定位权限-CLLocation详细使用方式
- SpringBoot | SpringBoot Web开发
- Tomcat在Java开发中的使用笔记
- 一款强大的快速开发脚手架,前后端分离,干掉 70% 重复工作!
- 在NVIDIA Jetson上开发要知道的知识点
- 玩机汇总(二):小米手机解锁与刷开发版
- 【Android NDK 开发】NDK C/C++ 代码崩溃调试 - Tombstone 报错信息日志文件分析 ( 使用 addr2line 命令行工具查找动态库中的报错代码位置 )
- iOS中加速度传感器的使用详解手机开发
- UIDatePicker使用详解手机开发
- 使用jqMobi开发app基础:Scrolling的使用,停止和继续拖动有关的问题详解手机开发
- 使用jqMobi开发app基础:使用 jQuery详解手机开发
- Java加载js详解手机开发
- SliferMenu详解手机开发
- Android Context.getSystemService() 与 ServiceManager 的理解和使用详解手机开发
- Python开发系列课程(6) – 要不要使用复杂表达式详解编程语言
- 开发环境极速搭建Linux下NDK开发环境(linux搭建ndk)
- Linux开发技术:走向未来(linux做开发)
- 处理Linux开发:让处理更加高效(基于linux的开发)
- 操作Linux分支操作:快速实现功能分支开发(linux的分支)
- Oracle开发大全引领新时代(oracle开发书籍推荐)
- Linux C语言开发——让系统更加强大(linux c 开发)
- 通过Redis实现高效的网络模块开发(redis 网络模块)
- phpcms模块开发之swfupload的使用介绍
- 探讨PHP使用eAccelerator的API开发详解
- 使用Python开发windowsGUI程序入门实例
- 30个经典的jQuery代码开发技巧