OpenHarmony图片处理——XmlGraphicsBatik

server/2024/9/22 13:47:03/

简介

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/server/11404.html

相关文章

python使用tkinter和ttkbootstrap制作UI界面(二)

这次讲解UI界面常用的主键,延续上文的框架进行编写,原界面如下: Combobox组件应用(下拉框) """Combobox组件"""global comvalue_operatorcomvalue_operator tk.StringVar()value_ope…

Ubuntu或Debian系统的漏洞修复:apt安装包管理工具

在阿里云主机管理后台->安全云中心,会看到系统最新的公布漏洞。 对于系统软件漏洞,我们还是要早做修复,防患于未然。 但安全云中心的功能大部分需要付费,包括一键修复,自己修复软件漏洞怎么操作呢? 其…

AI日报:最强大模型Llama 3发布;Midjourney推社交新功能Room;超强AI视频自动剪辑工具Captions;手机上可以玩大模型了

新鲜AI产品点击了解:https://top.aibase.com/ 1、最强大模型Llama3 正式发布 已达GPT4 级别 Llama3是Meta公司最新发布的开源模型,拥有80亿和700亿参数规模,预计7月正式发布。该模型具备多模态能力,集成了新的计算机编码功能&am…

电机控制专题(一)——最大转矩电流比MTPA控制

文章目录 电机控制专题(一)——最大转矩电流比MTPA控制前言理论推导仿真验证轻载1Nm重载30Nm 总结 电机控制专题(一)——最大转矩电流比MTPA控制 前言 MTPA全称为Max Torque Per Ampere,从字面意思就可以知道MTPA算法的目的是一个寻优最值问题,可以从以…

牛客NC195 二叉树的直径【simple DFS C++ / Java /Go/ PHP】

题目 题目链接: https://www.nowcoder.com/practice/15f977cedc5a4ffa8f03a3433d18650d 思路 最长路径有两种情况: 1.最长条路径经过根节点,那么只需要找出根节点的左右两棵子树的最大深度然后相加即可。 2.最长路径没有经过根节点&#xf…

破解生产瓶颈,提升时效性——蓝鹏测控推进效率革新

在日益激烈的市场竞争中,蓝鹏公司近日宣布采取一系列措施,旨在解决生产过程中的关键短板问题,特别是设计定稿延迟、原料采购不及时等问题,以确保生产部门能够按时完成订单,提高整体运营效率。 蓝鹏公司位于经济发展活…

大厂Redis高频面试题及参考答案(持续更新)

描述一下Redis的基本工作原理。 Redis(Remote Dictionary Server)是一个开源的,基于内存的高性能键值对数据库。它的基本工作原理可以分为以下几个方面: 内存存储:Redis将所有数据存储在内存中,这使得数据的读写速度非常快,可以支持每秒数十万次的读写操作。 数据持久化…

【后端】node.js安装与配置教程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、安装node.js二、验证安装三、配置 npm四、开发环境配置五、总结 前言 随着开发语言及人工智能工具的普及,使得越来越多的人会主动学习使用一些…