OpenHarmony图片处理——XmlGraphicsBatik

embedded/2024/9/22 19:54:59/

简介

XmlGraphicsBatik项目用于处理可缩放矢量图形(SVG)格式的图像,例如显示、生成、解析或者操作图像。

支持SVG图像的显示,可显示静态及动态SVG图像;

支持快捷生成SVG图像文件;

支持操作SVG图像进行颜色、样式、内容的修改;

支持将SVG图像的xml文本解析为可操作对象。

下载安装

ohpm install @ohos/xmlgraphicsbatik 

OpenHarmony ohpm 环境配置等更多内容,请参考如何安装 OpenHarmony ohpm 包

使用说明

对SVG图像进行生成、操作、解析等操作均依赖于SVGManager管理类

使用本库需要预先在MainAbility.ts 中预制文件路径: GlobalContext.getContext().setObject(“filesDir”, this.context.filesDir);

import {SVGManager} from '@ohos/XmlGraphicsBatik';private svgManager: SVGManager = SVGManager.getInstance();

1. 显示SVG图像

// Iamge组件支持显示media资源文件 及 工程目录中的SVG图片
Image($r('app.media.svgSample')).width(150).height(150)Image('file://' + this.filePath + '/svg.svg').width(150).height(150)

2. 生成SVG图像文件

2.1 创建SVG文件声明及子标签

// 创建SVG 对象:声明及SVG标签
this.svgManager.createSVGDeclares();// 获取SVG标签对应的对象
let svgTagObj = this.svgManager.getSVGRoot();// 构建SVG中的rect节点
let rect: SVGRect = new SVGRect();
rect.setX(50);
rect.setY(50);
rect.setRX(20);
rect.setRY(20);
rect.setWidth(100);
rect.setHeight(100);
rect.addAttribute('style', 'fill:rgb(255,0,255);stroke-width:2;stroke:rgb(0,0,0)')// 输出标准格式rect对象
let rectObj = rect.toObj();// 构建固定格式的节点描述对象
let svgFormatForRect: SVGSpecifiedFormat = new SVGSpecifiedFormat();
svgFormatForRect.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT);
svgFormatForRect.setElementName('rect');
svgFormatForRect.setAttributes(rectObj);if (svgTagObj) {// 为SVG标签添加固定格式的Rect子标签this.svgManager.addChildNode(svgTagObj, svgFormatForRect.toObj());consoleInfo('Test svg: add svg svgTotalRoot', JSON.stringify(this.svgManager.getSVGTotalObj()));
}// 获取整个SVG文件对应的对象
let svgTotalObj = this.svgManager.getSVGTotalObj();
let success = function () {consoleInfo('saveFile', 'success');
}// 将SVG文件对象保存为.svg格式文件,文件保存在 /project's path/files中
this.svgManager.saveSVG('svg.svg', svgTotalObj, success);

结果

add svg svgTotalRoot: {"declaration":{"attributes":{"version":"1.0","encoding":"utf-8","standalone":"yes"}},"elements":[{"type":"element","name":"svg","attributes":{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"},"elements":[{"type":"element","name":"rect","attributes":{"x":50,"y":50,"rx":20,"ry":20,"width":100,"height":100,"style":"fill:rgb(255,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]
}

2.2 手动创建SVG文件及子标签

// 清空已存在的SVG根
this.svgXMLRoot = this.svgManager.getSVGTotalObj();
this.svgManager.removeByKey(this.svgXMLRoot, SVGAttrConstants.ATTR_KEY_DECLARATION);
this.svgManager.removeByKey(this.svgXMLRoot, SVGAttrConstants.ATTR_KEY_ELEMENTS);// 构建SVG标签对应的对象
let svg: SVGRoot = new SVGRoot();
svg.setXMLNS(XMLConstants.XMLNS_NAMESPACE_URI_SVG);
svg.setXMLNSLink(XMLConstants.XLINK_NAMESPACE_URI);
svg.setSvgId('svgRoot');
svg.setXMLSpace(false);
svg.setWidth(250);
svg.setHeight(250);
svg.setViewBox(10, 10, 250, 250);
let svgObj = svg.toObj();let svgSpecifiedFormat: SVGSpecifiedFormat = new SVGSpecifiedFormat();
svgSpecifiedFormat.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT);
svgSpecifiedFormat.setElementName('svg');
svgSpecifiedFormat.setAttributes(svgObj);// 构建SVG标签内的Rect子标签的对象
let rect: SVGRect = new SVGRect();
rect.setX(50);
rect.setY(50);
rect.setRX(20);
rect.setRY(20);
rect.setWidth(100);
rect.setHeight(100);
rect.addAttribute('style', 'fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)')
let rectObj = rect.toObj();let svgFormatForRect: SVGSpecifiedFormat = new SVGSpecifiedFormat();
svgFormatForRect.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT);
svgFormatForRect.setElementName('rect');
svgFormatForRect.setAttributes(rectObj);
svgSpecifiedFormat.setElements(svgFormatForRect.toObj());if (this.svgXMLRoot) {// 构建SVG文件声明let declarationAttrs: object = {};declarationAttrs['version'] = '1.0';declarationAttrs['encoding'] = 'utf-8';declarationAttrs['standalone'] = 'no';let declarationObj: object = {};declarationObj[SVGAttrConstants.ATTR_KEY_ATTRIBUTES] = declarationAttrsthis.svgXMLRoot[SVGAttrConstants.ATTR_KEY_DECLARATION] = declarationObj;this.svgManager.addChildNode(this.svgXMLRoot, svgSpecifiedFormat.toObj());consoleInfo('Test svg: add line svgTotalRoot', JSON.stringify(this.svgManager.getSVGTotalObj()));
}

结果

Test svg: add svg svgTotalRoot: {"declaration":{"attributes":{"version":"1.0","encoding":"utf-8","standalone":"no"}},"elements":[{"type":"element","name":"svg","attributes":{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","id":"svgRoot","xml:space":"default","width":250,"height":250,"viewBox":{"x":10,"y":10,"width":250,"height":250}},"elements":[{"type":"element","name":"rect","attributes":{"x":50,"y":50,"rx":20,"ry":20,"width":100,"height":100,"style":"fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]
}

3. 操作SVG图像对象

3.1 修改已存在的子标签的属性

// 获取SVG根标签对应的操作对象
let svgRoot = this.svgManager.getSVGRoot();
if (!svgRoot) {consoleInfo('Test rect: update attr for rect1', 'svg tag is null');return false;
}// 根据主键获取对应的属性值
let svgElements = this.svgManager.getValueForKey(svgRoot, SVGAttrConstants.ATTR_KEY_ELEMENTS);
if (!svgElements) {consoleInfo('Test rect: update attr for rect1', `svg tag's elements is null`);return false;
}if (typeof svgElements !== SVGAttrConstants.TYPEOF_OBJECT || !Array.isArray(svgElements)) {consoleInfo('Test rect: update attr for rect1', `the elements's type of svg tag is not array`);return;
}let rectResult = null;
try {svgElements.forEach((item) => {if (typeof item === SVGAttrConstants.TYPEOF_OBJECT) {let nameValue: string = this.svgManager.getValueForKey(item, SVGAttrConstants.ATTR_KEY_NAME);if (nameValue === 'rect') {rectResult = item;throw 'has got rect,jump out';}}})
} catch (e) {if (!rectResult) {consoleInfo('Test rect: update attr for rect1', 'rect not exist');return;}if (typeof rectResult === SVGAttrConstants.TYPEOF_OBJECT) {let rectAttributes = rectResult[SVGAttrConstants.ATTR_KEY_ATTRIBUTES];rectAttributes['x'] = 20;rectAttributes['y'] = 20;rectAttributes['rx'] = 10;rectAttributes['ry'] = 50;rectAttributes['width'] = 80;rectAttributes['height'] = 80;// 为标签添加/设置属性键值对this.svgManager.setAttribute(rectAttributes, 'style', 'fill:rgb(0,255,0);stroke-width:10;stroke:rgb(0,255,255)');this.allAttrRectObj = rectResult;}consoleInfo('Test rect: update attr for rect1 svgTotalObj', JSON.stringify(this.svgManager.getSVGTotalObj()));
}

3.2 移除属性键值对

let attrs = this.svgManager.getValueForKey(rectOriginData, SVGAttrConstants.ATTR_KEY_ATTRIBUTES);
if (!attrs) {consoleInfo('test remove ' + firstAttrName, 'rect1 has no attributes');return;
}
this.svgManager.removeByKey(attrs, firstAttrName);

4. 解析SVG图像文件

this.svgManager.parse('svg.svg', (parseXMLResultObj) =>{this.svgJson = parseXMLResultObj;
})

结果

{"declaration":{"attributes":{"version":"1.0","encoding":"utf-8"}},"elements":[{"type":"element","name":"svg","attributes":{"id":"svgRoot","space":"default","width":"250","height":"250","viewBox":"10 10 250 250 "},"elements":[{"type":"element","name":"rect","attributes":{"x":"50","y":"50","rx":"20","ry":"20","width":"100","height":"100","style":"fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]
}

接口说明

  1. 获取SVG管理类实例
   static getInstance(): SVGManager
  1. 获取整个SVG文件对应的可以操作对象
   getSVGTotalObj(): object
  1. 创建SVG文件声明及SVG根标签
   createSVGDeclares(): object
  1. 获取SVG根标签对应的可操作对象
   getSVGRoot(obj: Object = this.svgObj): object
  1. 添加子标签(不覆盖原子标签)
   addChildNode(parentObj: Object, childPropertyValue: Object): boolean
  1. 设置子标签(覆盖原子标签)
   setChildNode(parentObj: Object, childPropertyValue: Object): boolean
  1. 通过主键获取对应属性值
   getValueForKey(parentObj: Object, key: string): any
  1. 根据主键移除键值对
   removeByKey(parentObj: Object, key: string): void
  1. 为对象设置属性或子节点(覆盖原有键值对)
   setAttribute(parentObj: Object, key: string, value: string): void
  1. 创建文件夹
    createFolder(path: string): void 
  1. 获取文件根路径
    getFilePath(onSuccess: (filesDir: string) => void): void
  1. 保存SVG文件
    saveSVG(fileName: string, fileContent: string | Object, onSuccess?: () => void, onFailed?: (number, Error) => void): void
  1. 解析SVG文件
    parse(fileName: string, onSuccess: (result: string) => void, onFailed?: (error: Error) => void): void

约束与限制

在下述版本验证通过:

DevEco Studio: 4.1 Canary(4.1.3.322), SDK: API11 (4.1.0.36)

DevEco Studio: 4.0 (4.0.3.600), SDK: API10 (4.0.10.11)

DevEco Studio: 4.0 (4.0.3.512), SDK: API10 (4.0.10.9)

DevEco Studio: 3.1 Beta2(3.1.0.400), SDK: API9 Release(3.2.11.9)

目录

/XmlGraphicsBatik       # 工程根目录
├── entry                  # 示例代码文件夹
├── library    # 三方库源码文件夹
│   └── src
│       ├── index.ets      # 对外暴露文件的存放目录
│       ├── package.json   # 项目介绍
│       └──main/ets/batik
│          ├── SVGManager.ets    # SVG处理管理核心类
│          ├── SVGXMLChecker.ets # 检查SVG文本是否合规
│          ├── StringReader.ets  # 读取SVG文本字符串工具类
│          └── constants
│              ├── RegexConstants.ets   # 正则表达式常量类
│              ├── SVGAttrConstants.ets # SVG标准格式主键常量类
│              ├── SVGXMLConstants.ets  # SVG文件常量类
│              └── XMLConstants.ets     # XML文件常量类
│          └── svggen
│              ├── SVGSpecifiedFormat.ets  # SVG文件对应的可操作对象标准格式构造类
│              ├── SVGDeclares.ets         # SVG文件声明构造类 
│              ├── SVGRoot.ets             # SVG文件根标签构造类
│              ├── SVGCircle.ets           # Ciecle子标签构造类
│              ├── SVGEllipse.ets          # Ellipse子标签构造类
│              ├── SVGLine.ets             # Line子标签构造类
│              ├── SVGPath.ets             # Path子标签构造类
│              ├── SVGRect.ets             # Rect子标签构造类
│              └── SVGPolygonAndPolyLine.ets # Polygon 及 PolyLine子标签构造类
│          └── tools
│              ├── DeleteProperty.ts            # Delete工具函数
│              ├── GetKeysTest.ts               # GetKeysDelete工具函数 
│              ├── GlobalContext.ets            # GlobalContext构造类
│              ├── IsArrayFunction.ts           # IsArray工具函数
│              ├── MakePropertiesImmutable.ts   # 冻结对象工具函数
│              ├── ObjCreate.ts                 # 创建空对象工具函数
│              └── StringToHex.ts               # 字符串转不同进制工具函数
│          └── util
│              ├── LogUtil.ets         # 日志打印工具类
│              ├── ObjOrArrayUtil.ets  # 可操作对象及Array处理工具类
│              └── XMLRules.ets        # XML文件固定规则工具类

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.
鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向


http://www.ppmy.cn/embedded/11569.html

相关文章

0-1 设计高质量数据可视化大屏

5 大指南塑造高阶可视化 可视化是个友好的媒介 理解数据是成为优秀媒介的关键 业务驱动下的设计策略 图扑设计的无限可能 创新思维让可视化更具价值 可视化是个友好的媒介 我们正处于一个数据泛滥的时代,随处可见数据的身影,更知其不可忽视的重要…

C#身份核验接口、身份证实名认证API、身份证OCR识别

实名认证是企业对客户资料真实性进行的一种有效的验证审核,有助于建立完善可靠的互联网信用基础,可预防一部分网络诈骗,其中,身份证实名认证是我们常见的基础验证方式,企业可通过核验身份证号、姓名、证件头像以及现场…

初入单元测试

单元测试:针对最小的功能单元(方法),编写测试代码对其进行正确性测试 Junit可以用来对方法进行测试,虽然是有第三方公司开发,但是很多开发工具已经集成了,如IDEA。 Junit 优点:可以灵活的编写测试代码&am…

人脸服务的算法内容

人脸算法可以返回在图像中找到的任何人脸的矩形坐标,以及与这些人脸相关的一系列属性,例如: 配饰:指示给定的人脸是否有配饰。 此属性会返回可能的配饰,包括头饰、眼镜和口罩,每个配饰的置信度分数介于 0 …

Jackson 2.x 系列【30】Spring Boot 集成之数据脱敏

有道无术,术尚可求,有术无道,止于术。 本系列Jackson 版本 2.17.0 本系列Spring Boot 版本 3.2.4 源码地址:https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 概述2. 实现思路3. 案例演示3.1 脱敏规则3.2 自…

混合现实(MR)技术的应用场景

混合现实(MR)技术将虚拟世界和现实世界融合在一起,用户可以在现实世界中看到和与虚拟物体进行交互,同时还可以感知周围的真实环境。MR技术具有广阔的应用前景,可以应用于各行各业。以下是一些MR的应用场景。北京木奇移…

RUST腐蚀服务器添加 TAGS标签教程

RUST腐蚀服务器添加 TAGS标签教程 大家好我是艾西,一个做服务器租用的网络架构师。我们自己搭建架设的服务器在steam展示面板看到跟别人的不一样是咋回事? 这个其实就是服务器的一个标签,那么主要的作用就是让大家在选择服务器时更快更直接的…

nmap、john、tcpdump

Kali是基于Debian的Linux发行版,Kali Linux包含上百个安全相关工具,如渗透测试、安全检测、密码安全、反向工程等。 扫描:获取一些公开、非公开信息为目的;检查潜在的风险、查找可攻击的目标、收集设备/主机/系统/软件信息、发现可…