harmony 鸿蒙图形绘制与显示实例
图形绘制与显示实例
前言
在Drawing开发指导中介绍了怎么通过调用NativeDrawing
提供的接口绘制出一个2D图形,本文档将会介绍如何把绘制出的2D图形显示在屏幕上,主要利用NativeWindow
和XComponent
模块提供的能力将图形显示在屏幕上。
开发步骤
以下步骤描述了在OpenHarmony中如何使用NativeDrawing
模块的画布画笔绘制一个基本的2D图形,并将图形内容写入NativeWindow
提供的图形Buffer
,提交Buffer
到图形队列,并利用XComponent
将C++代码层与ArkTS层对接,实现在ArkTS层调用绘制和显示逻辑,最终能在应用上显示图形。
添加动态链接库
CMakeLists.txt中添加以下lib。
libace_napi.z.so
libace_ndk.z.so
libnative_window.so
libnative_drawing.so
头文件
#include <ace/xcomponent/native_interface_xcomponent.h>
#include "napi/native_api.h"
#include <native_window/external_window.h>
#include <native_drawing/drawing_bitmap.h>
#include <native_drawing/drawing_color.h>
#include <native_drawing/drawing_canvas.h>
#include <native_drawing/drawing_pen.h>
#include <native_drawing/drawing_brush.h>
#include <native_drawing/drawing_path.h>
#include <cmath>
#include <algorithm>
#include <stdint.h>
#include <sys/mman.h>
获取OHNativeWindow实例,作为图形显示的载体。
- 在xxx.ets中添加一个XComponent组件。
ts XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'entry'})
- 在native c++层获取NativeXComponent。
c++ // 获取XComponent的id char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; napi_value exportInstance = nullptr; // 用来解析出被wrap了NativeXComponent指针的属性 napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance); OH_NativeXComponent *nativeXComponent = nullptr; // 通过napi_unwrap接口,解析出NativeXComponent的实例指针 napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
- 定义OH_NativeXComponent_Callback。
c++ // 声明一个XComponent的Callback OH_NativeXComponent_Callback callback; // 注册OnSurfaceCreated的回调函数 callback.OnSurfaceCreated = OnSurfaceCreatedCB;
- 将OH_NativeXComponent_Callback注册给NativeXComponent。
c++ // 注册回调函数,在回调函数实现绘制显示逻辑,当用户在ArkTS层调用XComponent时就能通过回调函数调用到此段逻辑 OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback);
- 定义OH_NativeXComponent_Callback。
- 在xxx.ets中添加一个XComponent组件。
获取OHNativeWindow实例,用于提供图形显示的载体。
设置OHNativeWindowBuffer的属性。使用
OH_NativeWindow_NativeWindowHandleOpt
设置OHNativeWindowBuffer
的属性。// 获取 OHNativeWindow 实例 OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window); // 设置 OHNativeWindowBuffer 的宽高 int32_t code = SET_BUFFER_GEOMETRY; uint64_t width; uint64_t height; int32_t ret = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height); // 这里的nativeWindow是从上一步骤中的回调函数中获得的 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height); // 设置 OHNativeWindowBuffer 的步长 code = SET_STRIDE; int32_t stride = 0x8; ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
从图形队列申请OHNativeWindowBuffer。
OHNativeWindowBuffer* buffer = nullptr; int fenceFd; // 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例 OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd); // 通过 OH_NativeWindow_GetBufferHandleFromNative 获取 buffer 的 handle BufferHandle* bufferHandle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
内存映射mmap,获取bufferHandle的内存虚拟地址。
// 使用系统mmap接口拿到bufferHandle的内存虚拟地址 uint8_t *mappedAddr = static_cast<uint8_t *>(mmap(bufferHandle->virAddr, bufferHandle->size, PROT_READ|PROT_WRITE, MAP_SHARED, bufferHandle->fd, 0)); if (mappedAddr == MAP_FAILED) { // mmap failed }
使用 Native Drawing 提供的API接口绘制一个五角星形状的2D图形。详细代码见Drawing开发指导。
将上一步绘制出的2D图形通过NativeWindow显示在屏幕上。
- 将Drawing绘制的图形内容写入OHNativeWindowBuffer。
c++ uint8_t *bitmapAddr = static_cast<uint8_t *>(OH_Drawing_BitmapGetPixels(cBitmap)); std::copy(bitmapAddr, bitmapAddr + (width * height * 4), mappedAddr);
- 提交OHNativeWindowBuffer到图形队列。
c++ // 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为OHNativeWindowBuffer全部有内容更改。 Region region{nullptr, 0}; // 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。 OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region);
- 取消内存映射munmap。
c++ // 内存使用完记得去掉内存映射 int result = munmap(mappedAddr, bufferHandle->size); if (result == -1) { // munmap failed }
- 将Drawing绘制的图形内容写入OHNativeWindowBuffer。
绘制显示效果示意图。
你可能感兴趣的鸿蒙文章
harmony 鸿蒙使用MindSpore Lite引擎进行模型推理
harmony 鸿蒙使用MindSpore Lite进行离线模型的转换及推理
0
赞
- 所属分类: 后端技术
- 本文标签:
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦