HarmonyOS鸿蒙Next中怎么展示SVG格式图片
HarmonyOS鸿蒙Next中怎么展示SVG格式图片 鸿蒙怎么展示复杂的SVG,用什么办法比较好。
类似接口返回这样的,图片资源是从接口获取的
<svg width="84" height="88" xmlns="http://www.w3.org/2000/svg">
<circle cx="40" cy="40" r="30" stroke="black" fill="red"/>
</svg>
这样的图片。我直接用Image(url) 展示不出来。
然后我用Web展示的,可以展示出来 但是感觉性能有点慢,有没有其他更好的方法。
if (!/viewBox/.test(svgStr)) {
svgStr = svgStr.replace(
/<svg\s+/,
'<svg viewBox="0 0 84 88" '
);
}
svgStr = svgStr.replace(
/<svg([^>]*)width=".*?"([^>]*)height=".*?"/,
'<svg$1 width="300"$2 height="300"'
);
const encodedSvg = encodeURIComponent(svgStr)
const dataUrl = `data:image/svg+xml;charset=utf-8,${encodedSvg}`
更多关于HarmonyOS鸿蒙Next中怎么展示SVG格式图片的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【背景知识】
- Image组件可显示矢量图(SVG格式的图片),SVG标签文档请参考SVG标签说明。如果SVG图片没有原始大小,需要给Image组件设置宽高,否则不显示。SVG图片不支持通过image标签引用svg格式和gif格式的本地其他图片。
- 加载SVG图片目前可行的方法有很多,例如下载为SVG文件,然后通过文件读取;或者解析为Uint8Array,然后转为PixelMap进行加载,目前转为PixelMap方式可行性更高。
【解决方案】
首先可以使用TextEncoder类的encodeInto方法,将SVG字符串转化为Uint8Array类型,然后使用createImageSource通过buffer创建ImageSource实例,最后使用createPixelMap返回结果,参考代码如下:
import { image } from '@kit.ImageKit';
import { util } from '@kit.ArkTS';
@Entry
@Component
struct Index {
@State pixelMap: image.PixelMap | undefined = undefined;
// 将以下内容替换成从三方库得到的SVG字符串
svgContent = '';
async uint8ArrayToPixelMap(svg: string): Promise<image.PixelMap> {
let encoder = new util.TextEncoder();
const uint8Array = encoder.encodeInto(svg);
const iconArray: ArrayBuffer = uint8Array.buffer.slice(0);
let source = image.createImageSource(iconArray);
const pixelMap = await source.createPixelMap();
source.release();
return pixelMap;
}
build() {
Column() {
Button('点击根据字符串加载SVG图片')
.onClick(() => {
this.uint8ArrayToPixelMap(this.svgContent).then((data: PixelMap) => {
this.pixelMap = data;
})
})
.margin({ top: 30, bottom: 30 })
Image(this.pixelMap)
.width('50%').height('50%')
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.margin({ top: 30, bottom: 30 })
}
.height('100%')
.width('100%')
}
}
更多关于HarmonyOS鸿蒙Next中怎么展示SVG格式图片的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,展示SVG图片需要使用Image组件,并设置src属性为SVG文件的资源路径。SVG文件需放在项目的resources/base/media/目录下。系统会自动解析并渲染SVG矢量图形。
在HarmonyOS Next中,直接使用Image组件加载SVG字符串确实无法显示。你遇到的性能问题,是因为Web组件渲染开销较大。针对从接口获取SVG字符串的场景,推荐以下两种更优方案:
方案一:使用 SvgImage 组件(推荐)
这是ArkUI为SVG提供的原生组件,性能最佳。
- 安装图形库:在
oh-package.json5中声明依赖"@ohos/graphics"。 - 转换与渲染:将获取到的SVG字符串转换为
PixelMap,再交给SvgImage展示。
此方案直接利用系统底层渲染引擎,避免了WebView的额外开销。import { SvgImage } from '@ohos/graphics'; // 假设 svgString 是从接口获取的SVG文本 let svgImageController: SvgImage.SvgImageController = new SvgImage.SvgImageController(); // 创建SvgImage对象并传入SVG字符串 let svgImage: SvgImage.SvgImage = svgImageController.createSvgImage(svgString); // 将SvgImage转换为PixelMap let pixelMap: image.PixelMap = svgImage.createPixelMap(); // 在UI中使用Image组件显示 Image(pixelMap) .width('100%') .height('100%')
方案二:转换为Base64 Data URL
如果 SvgImage 暂时无法满足复杂SVG(如包含特定滤镜或动画),可沿用你的转换思路,但需确保格式正确。
- 确保SVG格式完整:接口返回的SVG必须包含有效的XML命名空间(如你示例中的
xmlns="http://www.w3.org/2000/svg")。 - 进行URL编码:对你的代码稍作优化,确保特殊字符被正确处理。
// 对SVG字符串进行编码,注意处理换行和特殊字符 let encodedSvg = encodeURIComponent(svgStr.replace(/\s+/g, ' ').trim()); let dataUrl = `data:image/svg+xml;charset=utf-8,${encodedSvg}`; - 使用Image组件加载:
这种方式比Web组件轻量,但性能仍次于原生Image(dataUrl) .width('100%') .height('100%')SvgImage方案。
总结
- 首选
SvgImage组件:它是HarmonyOS Next为SVG渲染提供的原生支持,性能最优,兼容性由系统保证。 - 备选 Data URL:在
SvgImage无法处理的边缘情况下使用,注意确保字符串格式规范。 - 避免使用Web组件:仅当SVG包含大量交互或动画逻辑时才考虑,静态展示不推荐。
根据你的描述,接口返回的是标准SVG图形(如示例中的圆形),SvgImage 方案完全适用且能解决性能问题。

