鸿蒙(API 12 Beta3版)【使用Image完成图片解码】图片开发指导依赖JS对象

news2024/11/15 21:48:53

图片解码指将所支持格式的存档图片解码成统一的[PixelMap],以便在应用或系统中进行图片显示或[图片处理]。当前支持的存档图片格式包括JPEG、PNG、GIF、WebP、BMP、SVG、ICO、DNG。

开发步骤

添加依赖

在进行应用开发之前,开发者需要打开native工程的src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加libace_napi.z.so,libpixelmap_ndk.z.so,libimage_source_ndk.z.so,librawfile.z.so 以及日志依赖libhilog_ndk.z.so。

target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libpixelmap_ndk.z.so libimage_source_ndk.z.so librawfile.z.so)

添加接口映射

打开src/main/cpp/hello.cpp文件,在Init函数中添加getSyncPixelMap函数接口映射,作用是以同步的方式生成PixelMap,具体代码如下:

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_property_descriptor desc[] = {
        { "getSyncPixelMap", nullptr, getSyncPixelMap, nullptr, nullptr, nullptr, napi_default, nullptr },
    };

    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

JS侧调用

  1. 打开src\main\cpp\types\libentry\index.d.ts(其中libentry根据工程名生成),导入如下引用文件:
import { image } from '@kit.ImageKit';
import { resourceManager } from '@kit.LocalizationKit';

// 同步调用,入参为资源管理器和图片资源名称,返回PixelMap
export const getSyncPixelMap: (resMgr: resourceManager.ResourceManager, src: string) => image.PixelMap;
  1. 准备图片资源文件,本示例文件名为example.jpg,导入到src\main\resources\rawfile\ 路径下。

  2. 打开src\main\ets\pages\index.ets,导入"libentry.so(根据工程名生成)",调用Native接口,传入JS的资源对象。示例如下:

import testNapi from 'libentry.so'
import { image } from '@kit.ImageKit';

@Entry
@Component
struct Index {
  @State pixelMap : PixelMap | undefined = undefined;
  aboutToAppear() {
     // 调用自定义的getSyncPixelMap接口,获取pixelMap
     this.pixelMap = testNapi.getSyncPixelMap(getContext(this).resourceManager, "example.jpg")
  }

  build() {
     Row() {
        Column() {
        Image(this.pixelMap)
           .width(100)
           .height(100)
        }
        .width('100%')
     }
     .height('100%')
  }
}

Native接口调用

在hello.cpp文件中获取JS的资源对象,并转为Native的资源对象,即可调用Native接口,调用方式示例代码如下:

添加引用文件

   // 引入图片框架、raw文件、raw文件管理和日志打印头文件
   #include <cstdlib>
   #include <cstring>
   #include <multimedia/image_framework/image_source_mdk.h>
   #include <multimedia/image_framework/image_pixel_map_mdk.h>
   #include <rawfile/raw_file.h>
   #include <rawfile/raw_file_manager.h>
   #include <hilog/log.h>
   
   static napi_value getSyncPixelMap(napi_env env, napi_callback_info info)
   {
      size_t argc = 2;
      napi_value args[2] = {nullptr};

      napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
      
      napi_valuetype srcType;
      napi_typeof(env, args[0], &srcType);

      // 入参args[0]是资源管理器,用来初始化native层的资源管理器
      NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]);
      
      size_t strSize;
      char srcBuf[2048];
      // 入参args[1]是文件名称
      napi_get_value_string_utf8(env, args[1], srcBuf, sizeof(srcBuf), &strSize);

      // 用资源管理器打开Raw文件
      RawFile * rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, srcBuf);
      if (rawFile != NULL) {
         // 获取文件大小,并读取数据
         long len = OH_ResourceManager_GetRawFileSize(rawFile);
         uint8_t * data = static_cast<uint8_t *>(malloc(len));
         int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);

         OhosImageSource imageSource_c;
         imageSource_c.buffer = data;
         imageSource_c.bufferSize = len;

         OhosImageSourceOps ops{};
         napi_value imageSource;
         napi_value pixelMap;

         // 用读取到的Raw数据创建ImageSource
         int32_t ret = OH_ImageSource_Create(env, &imageSource_c, &ops, &imageSource);

         // 初始化native层的ImageSource
         ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);
         OhosImageDecodingOps decodingOps{};
         // 创建pixelMap
         OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);

         // 下列方法,为gif等动图格式提供。
         // napi_value pixelMapList;
         // OH_ImageSource_CreatePixelMapList(imageSourceNative_c, &decodingOps, &pixelMapList);
         // OhosImageSourceDelayTimeList list{};
         // OH_ImageSource_GetDelayTime(imageSourceNative_c, &list);
         // uint32_t count;
         // OH_ImageSource_GetFrameCount(imageSourceNative_c, &count);

         OhosImageSourceInfo info{};
         // 读取图片宽高
         OH_ImageSource_GetImageInfo(imageSourceNative_c, 0, &info);
         OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[decode]", "imageInfo width:%{public}d , height:%{public}d", info.size.width, info.size.height);
         
         // 读取图片源的ImageWidth配置参数并打印日志
         OhosImageSourceProperty target;
         char exifKey_c[] = "ImageWidth";
         target.size = strlen(exifKey_c);
         target.value = exifKey_c;

         OhosImageSourceProperty response{};
         response.size = 20;
         response.value = static_cast<char *>(malloc(20));
         OH_ImageSource_GetImageProperty(imageSourceNative_c, &target, &response);
         OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[decode]", "ImageProperty width after modify:%{public}s", response.value);

         // 处理完毕,释放native层资源
         OH_ImageSource_Release(imageSourceNative_c);
         OH_ResourceManager_CloseRawFile(rawFile);
         return pixelMap;
      }
      OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
      return nullptr;
   }

图片框架支持增量式解码,使用方法如下:

   // 引入图片框架、raw文件、raw文件管理和日志打印头文件
   #include <cstdlib>
   #include <cstring>
   #include <multimedia/image_framework/image_source_mdk.h>
   #include <multimedia/image_framework/image_pixel_map_mdk.h>
   #include <rawfile/raw_file.h>
   #include <rawfile/raw_file_manager.h>
   #include <hilog/log.h>
   
   static napi_value getSyncPixelMap(napi_env env, napi_callback_info info)
   {
      size_t argc = 2;
      napi_value args[2] = {nullptr};

      napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
      
      napi_valuetype srcType;
      napi_typeof(env, args[0], &srcType);

      // 入参args[0]是资源管理器,用来初始化native层的资源管理器
      NativeResourceManager * mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]);
      
      size_t strSize;
      char srcBuf[2048];
      // 入参args[1]是文件名称
      napi_get_value_string_utf8(env, args[1], srcBuf, sizeof(srcBuf), &strSize);

      // 用资源管理器打开Raw文件
      RawFile * rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, srcBuf);
      if (rawFile != NULL) {
         // 获取文件大小,若大于2048字节,则增量式解码,否则直接全部解码
         long len = OH_ResourceManager_GetRawFileSize(rawFile);
         if (len > 2048) {
            uint8_t * data = static_cast<uint8_t *>(malloc(len));
            // 读取文件全部数据
            int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);
            
            uint8_t * holderdata = static_cast<uint8_t *>(malloc(len));

            OhosImageSource imageSource_c;
            // imageSource_c的buffer分配了空间,但是数据是空的
            imageSource_c.buffer = holderdata;
            imageSource_c.bufferSize = len;
            OhosImageSourceOps ops{};
            napi_value imageSource;
            // 初始化增量ImageSource
            OH_ImageSource_CreateIncremental(env, &imageSource_c, &ops, &imageSource);

            // 初始化native层的ImageSource
            ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);

            // 以下模拟分片加载场景,分两次加载分片。第一次加载2048字节,第二次加载剩余的数据。
            OhosImageSourceUpdateData firstData{};
            firstData.buffer = data; // 图片数据
            firstData.bufferSize = len; // 图片数据总大小
            firstData.isCompleted = false;
            firstData.offset = 0; // 第一次重头开始加载
            firstData.updateLength = 2048; // 第一次加载了2048字节
            OH_ImageSource_UpdateData(imageSourceNative_c, &firstData);

            OhosImageSourceUpdateData secondData{};
            secondData.buffer = data;
            secondData.bufferSize = len;
            secondData.isCompleted = true; // 最后一次加载,要标记加载完成
            secondData.offset = 2048; // 已经加载过2048字节了,第二次偏移已经加载的量
            secondData.updateLength = len - 2048; // 第二次加载剩余的数据
            OH_ImageSource_UpdateData(imageSourceNative_c, &secondData);

            napi_value pixelMap;
            OhosImageDecodingOps decodingOps{};
            decodingOps.index = 0;
            // 创建pixelMap
            OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);

            // 处理完毕,释放native层资源
            OH_ImageSource_Release(imageSourceNative_c);
            OH_ResourceManager_CloseRawFile(rawFile);
            return pixelMap;
         } 
         // 读取Raw文件全部数据
         uint8_t * data = static_cast<uint8_t *>(malloc(len));
         int res = OH_ResourceManager_ReadRawFile(rawFile, data, len);

         OhosImageSource imageSource_c;
         imageSource_c.buffer = data;
         imageSource_c.bufferSize = len;

         OhosImageSourceOps ops{};
         napi_value imageSource;
         napi_value pixelMap;

         // 用读取到的Raw数据创建ImageSource
         int32_t ret = OH_ImageSource_Create(env, &imageSource_c, &ops, &imageSource);

         // 初始化native层的ImageSource
         ImageSourceNative * imageSourceNative_c = OH_ImageSource_InitNative(env, imageSource);
         OhosImageDecodingOps decodingOps{};

         // 创建pixelMap
         OH_ImageSource_CreatePixelMap(imageSourceNative_c, &decodingOps, &pixelMap);

         // 处理完毕,释放native层资源
         OH_ImageSource_Release(imageSourceNative_c);
         OH_ResourceManager_CloseRawFile(rawFile);
         return pixelMap;
      }
      OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
      return nullptr;
   }

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿
1

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

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

相关文章

YOLOv5改进 | 融合改进 | C3 融合Efficient Multi-Scale Conv提升检测效果

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录&#xff1a; 《YOLOv5入门 改…

博立的个人代表作品集锦

1. 比赛同创 国一_2023年全国大学生电子设计竞赛 【信号分离装置】 国二_2023年全国大学生集成电路创新创业大赛半决赛作品&#xff08;robei赛道&#xff09; 【基于robei EDA的可重构无线控制小车设计】 省一_2022年重庆市大学生电子设计竞赛 【混沌信号发生装置】 国…

Oracle RAC 集群启动顺序

大家好&#xff0c;这里是 Lucifer三思而后行&#xff0c;专注于提升数据库运维效率。 目录 前言Oracle 11GR2 RAC 集群启动顺序官方文档11GR212CR218C19C21C23ai 往期精彩文章推荐 前言 前几天使用脚本在 RockyLinux 9.4 安装 Oracle 11GR2 RAC&#xff0c;安装完之后发现集群…

Adobe Premiere Pro (PR2024)win/mac 视频编辑软件安装下载(附安装包)

一、软件概述 1.1 Premiere Pro 简介 Adobe Premiere Pro (简称PR) 是一款专业的视频编辑软件&#xff0c;广泛应用于电影、电视、广告、网络视频等多种视频制作领域。它提供了强大的编辑工具、丰富的特效和灵活的工作流程&#xff0c;帮助用户高效地完成从素材整理到最终输出…

[Linux#41][线程] 线程的特性 | 分离线程 | 并发的问题

1.线程的特性 进程和线程的关系如下图: 关于进程线程的问题 • 如何看待之前学习的单进程&#xff1f;具有一个线程执行流的进程 线程 ID 及进程地址空间布局 pthread_ create 函数会产生一个线程 ID&#xff0c;存放在第一个参数指向的地址中。 该线程 ID 和前面说的线程 ID …

持久化SSE对象

SpringBoot整合SSE&#xff0c;实现后端主动推送DEMO 前些日子写了整合SSE得demo。但是SSE对象是存储在ConcurrentHashMap<String, SseEmitter>中。在正式环境明显就不行了&#xff0c;服务重启一下的话都没有了。 那么要持久化&#xff0c;第一选择放redis 1、写了一个…

When Do We Not Need Larger Vision Models?

总结 传统观点挑战&#xff1a;传统上&#xff0c;扩大视觉模型的大小一直被认为是提升视觉表示能力和下游任务性能的关键途径。然而&#xff0c;本文重新审视了这一观点&#xff0c;提出了通过在不同图像尺度上运行较小的预训练视觉模型&#xff08;如ViT-B或ViT-L&#xff0…

Linux入门——11 线程

线程的概念&#xff0c;线程的控制&#xff0c;线程的同步和互斥&#xff0c;队列结构&#xff0c;线程池&#xff0c;锁 1.预备知识 1.1可重入函数 1.1.1链表的头插 main函数调用insert函数向一个链表head中插入节点node1,插入操作分为两步,刚做完第一步的时候,因为硬件中断…

续——网络通信编程

一、网络通信 1、编程 &#xff08;1&#xff09;基于UDP c/s通信模型 -------server——服务端——被动角色------- socket 全双工的&#xff08;可读可写&#xff09;。同上篇。 bind int bind(int sockfd , struct sockaddr *my_addr&#xff08;所绑定的地址信息&…

Linux的进程详解(进程创建函数fork和vfork的区别,资源回收函数wait,进程的状态(孤儿进程,僵尸进程),加载进程函数popen)

目录 什么是进程 Linux下操作进程的相关命令 进程的状态&#xff08;生老病死&#xff09; 创建进程系统api介绍&#xff1a; fork() 父进程和子进程的区别 vfork() 进程的状态补充&#xff1a; 孤儿进程 僵尸进程 回收进程资源api介绍&#xff1a; wait() waitpid…

编译运行 llama.cpp (vulkan, Intel GPU SYCL)

llama.cpp 是一个运行 AI (神经网络) 语言大模型的推理程序, 支持多种 后端 (backend), 也就是不同的具体的运行方式, 比如 CPU 运行, GPU 运行等. 但是编译运行 llama.cpp 并不是那么容易的, 特别是对于 SYCL 后端 (用于 Intel GPU), 坑那是一大堆. 只有特定版本的 llama.cpp…

【代码随想录训练营第42期 Day38打卡 - 动态规划Part6 - LeetCode 322. 零钱兑换 279.完全平方数 139.单词拆分

目录 一、做题心得 二、题目与题解 题目一&#xff1a;322. 零钱兑换 题目链接 题解&#xff1a;动态规划--完全背包 题目二&#xff1a; 279.完全平方数 题目链接 题解&#xff1a;动态规划--完全背包 题目三&#xff1a;139.单词拆分 题目链接 题解&#xff1a;动…

blender骨骼绑定(让物体动起来)

园哥摸索了两天了&#xff0c;骨骼做好就是不能带动物体&#xff0c;点击时候要选中那个骨骼点圆圈&#xff0c;点中间骨骼没用。终于动起来了。虽然有点奇怪。 点击图二那个点&#xff0c;貌似我的骨骼生长反了。做游戏是真麻烦。本来想搞个简单的2d游戏&#xff0c;结果那个瓦…

一起学Java(4)-[起步篇]教你掌握本协作项目中的Gralde相关配置文件(上)

将思绪拉回java-all-in-one项目&#xff0c;如果你fork并下载了代码&#xff0c;你会看到在项目中除了HelloWorldMain代码外&#xff0c;还存在很多文件。如果你并不了解他们的作用并有足够的好奇心&#xff0c;那你应该想要知道他们的作用。带着好奇&#xff0c;今天我也来研究…

网络抓包测试

利用fgets遇到\n停止的特性&#xff0c;给流数据直接加间隔&#xff0c;fgets读的时候会把soket缓冲区里面的数据全部放到fgets的缓冲区内&#xff0c;再读的时候就不能从套接字fd描述符读而是从fgets的fq里面读 行为1. 读取行为&#xff1a;•fgets 读取字符直到遇到换行符 \n…

下载ncurses操作步骤

https://invisible-island.net/ncurses/announce.htmlncurses-6.5.官网下载链接 选择下载版本

信刻离线文件单向导入系统

信刻针对不同数据单向导入的需求&#xff0c;按需推出的离线文件单向导入系统采用软硬件相结合的技术&#xff0c;支持信息导入申请、身份认证、光盘读取、病毒查杀、光盘复刻、光盘数据信息导入、审查审批、用户管理、日志管理、三权管理、数据加密、数据检查、校验、安全审计…

pd虚拟机 Parallels Desktop 19 for Mac安装教程【支持Intel和M芯片】

pd虚拟机 Parallels Desktop 19 for Mac安装教程【支持Intel和M芯片】 一、准备工作 二、开始安装 安装包内有三个软件 Parallels Desktop是一款广受好评的Mac虚拟机软件&#xff0c;本文来讲述一下Parallels Desktop是如何下载、安装、激活与换机的。 Parallels Desktop 下…

外排序之文件归并排序实现

外排序介绍 外排序是指能够处理极大量数据的排序算法。通常来说&#xff0c;外排序处理的数据不能一次装入内存&#xff0c;只能放在读写较慢的外存储器(通常是硬盘)上。外排序通常采用的是⼀种“排序-归并”的策略。在排序阶段&#xff0c;先读入能放在内存中的数据量&#x…

【Kafka源码走读】消息生产者与服务端的连接过程

说明&#xff1a;以下描述的源码都是基于最新版&#xff0c;老版本可能会有所不同。 一. 查找源码入口 kafka-console-producer.sh是消息生产者的脚本&#xff0c;我们从这里入手&#xff0c;可以看到源码的入口&#xff1a; if [ "x$KAFKA_HEAP_OPTS" "x&qu…