XComponent、NativeDrawing实现2D图形绘制

XComponent、NativeDrawing实现2D图形绘制

HarmonyOS
2024-05-21 22:07:17
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
lovingkane

Native Drawing模块提供了一系列的接口用于基本图形和字体的绘制,今天我们主要直线绘图功能

Drawing绘制的内容无法直接在屏幕上显示,需要借用XComponent以及Native Window的能力支持,将绘制的内容通过Native Window送显。

开发流程:

1. 在界面中定义Xcomponent

2. 模块注册,注册接口函数,从而将封装的C++方法传递出来,供JS侧调用

3. 注册Component事件回调,使用NAPI实现XComponent事件回调函数

4. 初始化环境

5. 渲染功能实现

6. 注册与编译,使用CMake工具链将C++源代码编译成动态链接库文件

使用的核心API

Xcomponent

NativeBuffer

NativeDarwing

NativeWindow

核心代码解释

1.在界面中定义Xcomponent,

id : 与XComponent组件为一一对应关系,不可重复。通常开发者可以在native侧通过OH_NativeXComponent_GetXComponentId接口来获取对应的id从而绑定对应的XComponent;

libraryname:加载模块的名称,必须与在native侧Napi模块注册时nm_modname的名字一致。

2.使用NAPI获取XComponent实例指针,注册XComponent回调函数

1、实例NativeWindow、NativeBuffer,创建环境

2、绘制2d图形

/** 
    * 使用 Native Drawing 提供的API接口绘制 
    */ 
  { 
      // 创建一个bitmap对象 
      OH_Drawing_Bitmap *cBitmap = OH_Drawing_BitmapCreate(); 
      // 定义bitmap的像素格式 
      OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE}; 
      // 构造对应格式的bitmap 
      OH_Drawing_BitmapBuild(cBitmap, width, height, &cFormat); 
      // 创建一个canvas对象 
      OH_Drawing_Canvas *cCanvas = OH_Drawing_CanvasCreate(); 
      // 将画布与bitmap绑定,画布画的内容会输出到绑定的bitmap内存中 
      OH_Drawing_CanvasBind(cCanvas, cBitmap); 
      // 使用白色清除画布内容 
      OH_Drawing_CanvasClear(cCanvas, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF)); 
    /** 
      * 画2D图形 
      */ 
      int len = 300; 
​ 
      float aX = 500; 
      float aY = 500; 
​ 
      float dX = aX - len * std::sin(18.0f); 
      float dY = aY + len * std::cos(18.0f); 
​ 
      float cX = aX + len * std::sin(18.0f); 
      float cY = dY; 
​ 
      float bX = aX + (len / 2.0); 
      float bY = aY + std::sqrt((cX - dX) * (cX - dX) + (len / 2.0) * (len / 2.0)); 
​ 
      float eX = aX - (len / 2.0); 
      float eY = bY; 
​ 
      // 创建一个path对象,然后使用接口连接成一个五角星形状 
      OH_Drawing_Path *cPath = OH_Drawing_PathCreate(); 
      // 指定path的起始位置 
      OH_Drawing_PathMoveTo(cPath, aX, aY); 
      // 用直线连接到目标点 
      OH_Drawing_PathLineTo(cPath, bX, bY); 
      OH_Drawing_PathLineTo(cPath, cX, cY); 
      OH_Drawing_PathLineTo(cPath, dX, dY); 
      OH_Drawing_PathLineTo(cPath, eX, eY); 
      // 闭合形状,path绘制完毕 
      OH_Drawing_PathClose(cPath); 
      // 创建一个画笔Pen对象,Pen对象用于形状的边框线绘制 
      OH_Drawing_Pen *cPen = OH_Drawing_PenCreate(); 
      OH_Drawing_PenSetAntiAlias(cPen, true); 
      OH_Drawing_PenSetColor(cPen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00)); 
      OH_Drawing_PenSetWidth(cPen, 10.0); 
      OH_Drawing_PenSetJoin(cPen, LINE_ROUND_JOIN); 
      // 将Pen画笔设置到canvas中 
      OH_Drawing_CanvasAttachPen(cCanvas, cPen); 
​ 
      // 创建一个画刷Brush对象,Brush对象用于形状的填充 
      OH_Drawing_Brush *cBrush = OH_Drawing_BrushCreate(); 
      OH_Drawing_BrushSetColor(cBrush, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0xFF, 0x00)); 
​ 
      // 将Brush画刷设置到canvas中 
      OH_Drawing_CanvasAttachBrush(cCanvas, cBrush); 
      // 在画布上画path的形状,五角星的边框样式为pen设置,颜色填充为Brush设置 
      OH_Drawing_CanvasDrawPath(cCanvas, cPath); 
      // 销毁创建的对象 
      OH_Drawing_BrushDestroy(cBrush); 
      OH_Drawing_PenDestroy(cPen); 
      OH_Drawing_PathDestroy(cPath); 
      // 画完后获取像素地址,地址指向的内存包含画布画的像素数据 
      // 
      uint8_t *bitmapAddr = static_cast<uint8_t *>(OH_Drawing_BitmapGetPixels(cBitmap)); 
      std::copy(bitmapAddr, bitmapAddr + (width * height * 4), mappedAddr); 
​ 
      //       void *bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap); 
      //       std::copy(addr, addr + addrSize, static_cast<uint8_t *>(bitmapAddr)); 
      //       const void *bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap); 
      //       memcpy(mappedAddr, bitmapAddr, width * height * 4); 
​ 
      // 销毁canvas对象 
      OH_Drawing_CanvasDestroy(cCanvas); 
      // 销毁bitmap对象 
      OH_Drawing_BitmapDestroy(cBitmap); 
      /**/ 
      

3、绘制内容送显

// 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为OHNativeWindowBuffer全部有内容更改。 
  Region region{nullptr, 0}; 
  // 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。 
  OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region); 
  // 取消内存映射munmap 
  // 内存使用完记得去掉内存映射 
  int result = munmap(mappedAddr, bufferHandle->size); 
  if (result == -1) { 
      // munmap failed 
  }

实现效果

注明适配的版本信息

DevEco Studio Version: 4.0.1.601

SDK:HarmoneyOS 4.0.10.11

分享
微博
QQ
微信
回复
2024-05-22 20:21:17
相关问题
XComponent、openGL实现3D图形绘制
452浏览 • 1回复 待解决
使用Drawing进行2d图像绘制
404浏览 • 1回复 待解决
使用Native、XComponent和EGL绘制图形
465浏览 • 1回复 待解决
使用Drawing实现图形绘制与显示
362浏览 • 1回复 待解决
鸿蒙如何实现位图绘制
8195浏览 • 1回复 待解决
通过Native 调用c++层实现文本绘制
442浏览 • 1回复 待解决
图形图像开发场景实践
297浏览 • 1回复 待解决
Xcomponent绘图流程分析
445浏览 • 1回复 待解决
有谁知道是否支持实现3D效果
671浏览 • 1回复 待解决
XComponent使用OpenGl ES
211浏览 • 1回复 待解决
如何操作canvas重新绘制
351浏览 • 1回复 待解决
XComponent 怎么设置为透明
754浏览 • 1回复 待解决
Xcomponent、NativeImage开发指导
422浏览 • 1回复 待解决
SurfaceProvider绘制延迟
5990浏览 • 4回复 已解决
xComponent组件帧率怎么统计?
241浏览 • 1回复 待解决