#HarmonyOS NEXT体验官# 基于鸿蒙Next的App(创意工坊)解析8:导出图像 原创
在前面几篇文章中,讲解了通过fabric完成各种处理图像的工作,当处理完图像后,就需要将我们的成果导出,“创意工坊”提供了强大的图像导出功能,允许导出为各种格式,如图所示:
从图中可以看出,可以导出为SVG、PNG、JPG和WebP格式。下面是对这几种图像格式的详细解释:
1. SVG (Scalable Vector Graphics)
概述:
SVG 是一种基于 XML(可扩展标记语言)的矢量图形格式。它主要用于展示二维图形,例如图标、插图、图表等。因为 SVG 是基于矢量的,它在缩放时不会失真,适合在网页和移动设备上使用。
特点:
- 可缩放性:SVG 图像是矢量图形,可以无损缩放到任意大小。这使它特别适合用于响应式设计和需要不同尺寸的图标。
- 可编辑性:因为 SVG 是纯文本文件,可以使用文本编辑器直接编辑图像的 XML 代码,还可以通过 CSS 和 JavaScript 进行样式和行为的动态修改。
- 文件大小:SVG 文件通常比位图格式(如 PNG、JPG)小得多,尤其是当图像包含很多重复元素时,这些元素可以通过简单的 XML 标签表示。
- 支持动画:SVG 支持使用 SMIL(Synchronized Multimedia Integration Language)或 CSS3 进行动画设计,这使其可以用来创建复杂的动画效果。
- 兼容性:现代浏览器都支持 SVG,但在某些老旧浏览器中可能需要使用 polyfills 来实现兼容。
使用场景:
- 图标和插图:因为其缩放能力和可编辑性,SVG 常用于网站图标和插图。
- 图表和地图:SVG 的结构化数据格式使其非常适合表示图表和地图,这些图表可以通过 CSS 和 JavaScript 动态更新。
- 动画效果:可以使用 SVG 制作复杂的动画效果,同时保持高质量。
2. PNG (Portable Network Graphics)
概述:
PNG 是一种无损压缩的位图图像格式,专为互联网图像传输设计。它支持透明背景,因此在网页设计中被广泛使用。
特点:
- 无损压缩:PNG 格式在压缩图像时不会丢失任何数据,因此图像质量高,适合需要精确颜色表现的图像,如标志、图标和截图。
- 透明度支持:PNG 支持 8 位或 24 位颜色深度的透明通道(alpha 通道),可以部分或完全透明。这使它非常适合用于网页设计中的图像叠加。
- 文件大小:虽然 PNG 支持无损压缩,但文件大小通常比 JPG 等有损压缩格式大,尤其是在存储复杂的图像时。
- 兼容性:PNG 格式受到广泛支持,几乎所有的网页浏览器和图像编辑工具都可以打开和处理 PNG 图像。
使用场景:
- 网站设计:因为其透明背景支持,PNG 常用于网页设计中的按钮、图标和其他需要透明背景的元素。
- 图表和截图:由于其无损压缩和高质量表现,PNG 非常适合存储图表、截图和图形设计作品。
- 电子邮件和在线传输:因为其高质量和无损压缩,PNG 常用于需要高保真度的图像传输。
3. JPG/JPEG (Joint Photographic Experts Group)
概述:
JPG(或 JPEG)是一种有损压缩的位图图像格式,专为存储和传输照片和高色彩深度的图像而设计。它是最广泛使用的图像格式之一,特别适合存储摄影图像。
特点:
- 有损压缩:JPG 通过舍弃一些细节信息来减少文件大小,这会导致图像质量的下降,尤其是在高压缩率下。然而,在适中的压缩率下,JPG 能够在质量和文件大小之间达到较好的平衡。
- 色彩表现:JPG 支持 24 位颜色深度(即 1677 万种颜色),非常适合表现复杂的颜色过渡,如照片和写实的图像。
- 文件大小:由于有损压缩,JPG 文件通常比 PNG 小得多,适合在网页和移动应用中使用。
- 兼容性:JPG 格式被所有的图像编辑工具和浏览器广泛支持,是互联网上最常见的图像格式之一。
使用场景:
- 数码摄影:JPG 是数码相机和手机摄影的默认格式,适合存储和分享高质量的照片。
- 网页图片:因为文件小且加载速度快,JPG 常用于网站的背景图片、广告图片和内容图片。
- 电子邮件和社交媒体:JPG 是传输和分享照片的主要格式,因为它的文件较小且质量较高。
4. WebP
概述:
WebP 是由 Google 开发的一种现代图像格式,旨在同时支持有损和无损压缩。WebP 提供了比 JPG 和 PNG 更高效的压缩算法,在保持图像质量的同时大大减小文件大小。
特点:
- 有损和无损压缩:WebP 同时支持有损和无损两种压缩方式,用户可以根据需求选择。无损压缩可以在保持图像质量的情况下减少文件大小,而有损压缩则能够在一定程度上牺牲质量来进一步减小文件大小。
- 透明度支持:WebP 支持透明度(alpha 通道),这使它可以替代 PNG 格式,且通常情况下文件大小更小。
- 动画支持:WebP 还支持动画,可以替代 GIF 格式,用于创建文件较小且质量更高的动画图片。
- 文件大小:相比 PNG 和 JPG,WebP 通常可以提供更小的文件大小,同时保持相似甚至更好的图像质量。
- 兼容性:虽然 WebP 的支持在逐渐扩大,但并非所有的浏览器和应用程序都完全支持它。因此,在使用 WebP 时,通常需要提供其他格式的图像作为备用。
使用场景:
- 网页优化:WebP 格式非常适合需要优化网页加载速度的场景,因为它可以在保证图像质量的同时减少文件大小,提升页面加载速度。
- 移动应用:由于其小文件大小和高质量,WebP 适用于带宽有限或需要高效图像传输的移动应用。
- 动画和图形设计:WebP 支持高质量的动画效果,可以替代传统的 GIF 动画,并提供更小的文件大小和更高的图像质量。
总结
这四种图像格式各自有其独特的优势和使用场景:
- SVG 适用于需要无损缩放和编辑的矢量图形。
- PNG 适用于需要透明背景和高质量无损图像的场景。
- JPG 适用于需要平衡图像质量和文件大小的照片和写实图像。
- WebP 适用于需要最大化图像压缩效率,同时保持高质量和透明支持的现代网页和应用。
为了实现如图的导出窗口,需要使用Export组件。Export组件的代码如下:
完整代码示例及详细中文注释
以下是这段代码的完整版本,附带详细的中文注释,帮助您理解其功能和实现细节。
// 引入常量,用于设置面板和按钮的背景颜色,保证界面的一致性
import { PANEL_BACKGROUND_COLOR, PANEL_BUTTON_BACKGROUND_COLOR } from '../common/const';
// 引入与文档尺寸相关的常量,可能用于控制导出图像的尺寸
import { DocumentSize, DocumentSizes } from '../data/Documents';
// 引入 EntryAbility 模块,提供应用程序的全局路径信息
import EntryAbility from '../entryability/EntryAbility';
// 引入文件处理相关的工具函数,检查文档是否存在和创建文档目录
import { documentExists, createDocumentDir } from '../common/common';
// 使用 @Entry 装饰器标记这个组件为应用的入口组件,表示它会在应用启动时自动加载并显示
@Entry
// 使用 @Component 装饰器定义一个组件,名为 Export,包含了组件的逻辑和 UI 布局
@Component
export struct Export {
// 定义一个可选的回调函数,用于在用户选择了图像格式后,将选中的格式名称传递出去
formatSelected?: (formatName: string) => void;
// 从 EntryAbility 模块获取应用程序的根路径,可能用于存储导出的图像文件
rootPath: string = EntryAbility.rootPath;
// 使用 @State 定义一个状态变量,用于存储用户选择的图像格式名称,初始值为空字符串
@State formatName: string = '';
// build() 方法是组件的核心方法,用于定义组件的 UI 布局和行为
build() {
// 使用 Column 组件创建一个垂直布局的容器,子组件将按照顺序从上到下排列
Column() {
// 创建一个按钮组件,用于用户点击选择 SVG 格式导出图像
Button({ type: ButtonType.Normal }) {
// 在按钮内显示的文本内容为“SVG(矢量图)”
Text('SVG(矢量图)')
.fontSize(16) // 设置字体大小
.fontColor('#FFFFFF') // 设置字体颜色
.width('100%') // 设置文本的宽度为 100%
.height('100%') // 设置文本的高度为 100%
.textAlign(TextAlign.Center); // 设置文本居中对齐
}
.borderRadius(5) // 设置按钮的圆角半径,使按钮看起来更圆滑
.width(200) // 设置按钮的宽度为 200
.height(30) // 设置按钮的高度为 30
.margin({bottom:10, top:10}) // 设置按钮的上下边距
.onClick(() => {
// 设置按钮的点击事件,点击按钮时会检查 formatSelected 回调函数是否存在
if (this.formatSelected) {
this.formatSelected('svg'); // 调用回调函数并传递 'svg' 作为参数
}
});
// 创建一个按钮组件,用于用户点击选择 PNG 格式导出图像
Button({ type: ButtonType.Normal }) {
// 在按钮内显示的文本内容为“PNG(透明图)”
Text('PNG(透明图)')
.fontSize(16) // 设置字体大小
.fontColor('#FFFFFF') // 设置字体颜色
.width('100%') // 设置文本的宽度为 100%
.height('100%') // 设置文本的高度为 100%
.textAlign(TextAlign.Center); // 设置文本居中对齐
}
.borderRadius(5) // 设置按钮的圆角半径,使按钮看起来更圆滑
.width(200) // 设置按钮的宽度为 200
.height(30) // 设置按钮的高度为 30
.margin({bottom:10}) // 设置按钮的下边距
.onClick(() => {
// 设置按钮的点击事件,点击按钮时会检查 formatSelected 回调函数是否存在
if (this.formatSelected) {
this.formatSelected('png'); // 调用回调函数并传递 'png' 作为参数
}
});
// 创建一个按钮组件,用于用户点击选择 JPG 格式导出图像
Button({ type: ButtonType.Normal }) {
// 在按钮内显示的文本内容为“JPG(压缩图)”
Text('JPG(压缩图)')
.fontSize(16) // 设置字体大小
.fontColor('#FFFFFF') // 设置字体颜色
.width('100%') // 设置文本的宽度为 100%
.height('100%') // 设置文本的高度为 100%
.textAlign(TextAlign.Center); // 设置文本居中对齐
}
.borderRadius(5) // 设置按钮的圆角半径,使按钮看起来更圆滑
.width(200) // 设置按钮的宽度为 200
.height(30) // 设置按钮的高度为 30
.margin({bottom:10}) // 设置按钮的下边距
.onClick(() => {
// 设置按钮的点击事件,点击按钮时会检查 formatSelected 回调函数是否存在
if (this.formatSelected) {
this.formatSelected('jpg'); // 调用回调函数并传递 'jpg' 作为参数
}
});
// 创建一个按钮组件,用于用户点击选择 WebP 格式导出图像
Button({ type: ButtonType.Normal }) {
// 在按钮内显示的文本内容为“WebP(优化压缩图)”
Text('WebP(优化压缩图)')
.fontSize(16) // 设置字体大小
.fontColor('#FFFFFF') // 设置字体颜色
.width('100%') // 设置文本的宽度为 100%
.height('100%') // 设置文本的高度为 100%
.textAlign(TextAlign.Center); // 设置文本居中对齐
}
.borderRadius(5) // 设置按钮的圆角半径,使按钮看起来更圆滑
.width(200) // 设置按钮的宽度为 200
.height(30) // 设置按钮的高度为 30
.margin({bottom:10}) // 设置按钮的下边距
.onClick(() => {
// 设置按钮的点击事件,点击按钮时会检查 formatSelected 回调函数是否存在
if (this.formatSelected) {
this.formatSelected('webp'); // 调用回调函数并传递 'webp' 作为参数
}
});
}
// 设置 Column 容器的样式
.backgroundColor(PANEL_BACKGROUND_COLOR) // 设置背景颜色
.border({ width: 0, color: '#000000', radius: 10 }) // 设置边框属性
.width('100%') // 设置宽度为 100%,占据整个父容器的宽度
.height('100%'); // 设置高度为 100%,占据整个父容器的高度
}
}
代码详细注释与解释
这段 ArkTS 代码实现了一个用于选择图像导出格式的用户界面。用户可以从多个按钮中选择不同的图像格式(如 SVG、PNG、JPG、WebP),并通过回调函数传递所选格式。以下是对代码的逐行注释和实现过程的详细解释。
import { PANEL_BACKGROUND_COLOR, PANEL_BUTTON_BACKGROUND_COLOR } from '../common/const'
import { DocumentSize, DocumentSizes } from '../data/Documents'
import EntryAbility from '../entryability/EntryAbility'
import {documentExists, createDocumentDir} from '../common/common'
- 引入常量和模块:
- PANEL_BACKGROUND_COLOR 和 PANEL_BUTTON_BACKGROUND_COLOR:从外部模块引入面板和按钮的背景颜色常量,以确保界面的一致性。
- DocumentSize 和 DocumentSizes:导入与文档尺寸相关的常量(尽管在这段代码中未使用),通常用于控制导出图像的尺寸。
- EntryAbility:这是一个入口功能模块,提供了应用程序的全局路径信息,如
rootPath
,在图像导出时可能会用到。 - documentExists 和 createDocumentDir:引入文件处理相关的实用函数,分别用于检查文档是否存在和创建文档目录(在当前代码中未直接使用)。
@Entry
@Component
export struct Export {
- 定义组件:
- @Entry:标记这个组件为应用的入口组件,表示它会在应用启动时自动加载并显示。
- @Component:这是 ArkTS 中的一个装饰器,用于定义一个组件。
Export
是组件的名称,它包含了组件的逻辑和 UI 布局。
formatSelected?: (formatName: string) => void
rootPath: string = EntryAbility.rootPath;
@State formatName: string = '';
- 状态变量和回调函数:
- formatSelected:一个可选的回调函数,用于在用户选择了图像格式后,将选中的格式名称传递出去。
- rootPath:从
EntryAbility
模块获取应用程序的根路径,这个路径可能用于存储导出的图像文件。 - formatName:这是一个状态变量,用于存储用户选择的图像格式名称。在这里初始化为空字符串。
build() {
Column() {
- 构建 UI:
- build() 方法:这是组件的核心方法,用于定义组件的 UI 布局和行为。UI 元素的排列和样式都在这里定义。
- Column:这是一个垂直布局的容器组件,它的子组件会按照顺序从上到下排列。
Button({ type: ButtonType.Normal }) {
Text('SVG(矢量图)')
.fontSize(16)
.fontColor('#FFFFFF')
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
.borderRadius(5)
.width(200)
.height(30)
.margin({bottom:10, top:10})
.onClick(() =>{
if(this.formatSelected) {
this.formatSelected('svg');
}
})
- SVG 导出按钮:
- Button:按钮组件,用于用户点击选择 SVG 格式导出图像。
- Text:按钮内的文本内容为“SVG(矢量图)”,并设置了文本的字体大小、颜色、宽度、高度和居中对齐。
- borderRadius:按钮的圆角半径,使按钮看起来更圆滑。
- width 和 height:设置按钮的宽度和高度。
- margin:设置按钮的上下边距,避免按钮之间过于拥挤。
- onClick:设置按钮的点击事件,点击按钮时会检查
formatSelected
回调函数是否存在,如果存在则调用它并传递'svg'
作为参数,表示用户选择了 SVG 格式。
- Button:按钮组件,用于用户点击选择 SVG 格式导出图像。
Button({ type: ButtonType.Normal }) {
Text('PNG(透明图)')
.fontSize(16)
.fontColor('#FFFFFF')
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
.borderRadius(5)
.width(200)
.height(30)
.margin({bottom:10})
.onClick(() =>{
if(this.formatSelected) {
this.formatSelected('png');
}
})
- PNG 导出按钮:
- Button:按钮组件,用于选择 PNG 格式导出图像。
- Text:显示为“PNG(透明图)”,其余属性与 SVG 按钮类似。
- onClick:点击按钮时会触发
formatSelected('png')
,表示用户选择了 PNG 格式。
Button({ type: ButtonType.Normal }) {
Text('JPG(压缩图)')
.fontSize(16)
.fontColor('#FFFFFF')
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
.borderRadius(5)
.width(200)
.height(30)
.margin({bottom:10})
.onClick(()=>{
if(this.formatSelected) {
this.formatSelected('jpg');
}
})
- JPG 导出按钮:
- Button:按钮组件,用于选择 JPG 格式导出图像。
- Text:显示为“JPG(压缩图)”,其余属性与前面按钮类似。
- onClick:点击按钮时会触发
formatSelected('jpg')
,表示用户选择了 JPG 格式。
Button({ type: ButtonType.Normal }) {
Text('WebP(优化压缩图)')
.fontSize(16)
.fontColor('#FFFFFF')
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
.borderRadius(5)
.width(200)
.height(30)
.margin({bottom:10})
.onClick(() =>{
if(this.formatSelected) {
this.formatSelected('webp');
}
})
- WebP 导出按钮:
- Button:按钮组件,用于选择 WebP 格式导出图像。
- Text:显示为“WebP(优化压缩图)”,其余属性与前面按钮类似。
- onClick:点击按钮时会触发
formatSelected('webp')
,表示用户选择了 WebP 格式。
}.backgroundColor(PANEL_BACKGROUND_COLOR)
.border({ width: 0, color: '#000000', radius: 10 })
.width('100%')
.height('100%')
- 面板设置:
- backgroundColor:设置整个面板的背景颜色,使用之前引入的常量
PANEL_BACKGROUND_COLOR
。 - border:设置面板的边框属性,宽度为 0,颜色为黑色,圆角半径为 10。
- width 和 height:设置面板的宽度和高度为 100%,即占据整个父容器的空间。
- backgroundColor:设置整个面板的背景颜色,使用之前引入的常量
实现原理和步骤
-
组件初始化:
- 在组件定义时,引入了相关的常量、模块和工具函数,并设置了根路径和状态变量。这些变量和工具函数在实际操作时可能会用到,虽然在当前的代码实现中主要是为了展示而存在。
-
UI 构建:
- 使用
build()
方法构建用户界面,界面主要由一列按钮组成,每个按钮代表一种图像导出格式(如 SVG、PNG、JPG、WebP)。这些按钮排列在一个垂直的Column
容器中。
- 使用
-
按钮行为:
- 每个按钮都绑定了一个
onClick
事件处理程序,当用户点击按钮时,会调用回调函数formatSelected
并传递相应的格式名称。这个回调函数用于将用户选择的导出格式传递给外部调用方,以便执行后续的图像导出操作。
- 每个按钮都绑定了一个
-
界面样式:
- 设置了面板和按钮的样式,包括背景颜色、边框、圆角半径、宽度、高度和间距。这些样式保证了界面的一致性和美观性。
-
格式选择逻辑:
- 当用户点击某个按钮时,检查
formatSelected
回调函数是否存在,如果存在则调用它并传递所选格式。这样外部逻辑可以根据用户选择的格式执行相应的图像导出操作。
当选择完特效后,就会调用formatSelected函数,用于处理图像特效,该函数的代码如下:
- 当用户点击某个按钮时,检查
formatSelected(formatName: string) {
this.controller1.runJavaScript(`resetCanvasPosition()`).then(value => {
this.controller1.runJavaScript(`getImageBase64FromCanvas("${formatName}")`)//
.then(data => {
let uri = '';
try {
let PhotoSaveOptions = new picker.PhotoSaveOptions();
//保存图片默认名称
PhotoSaveOptions.newFileNames = [this.currentDocumentName + '.' + formatName];
let photoPicker = new picker.PhotoViewPicker();
//调起系统的图片保存功能
photoPicker.save(PhotoSaveOptions).then((PhotoSaveResult) => {
uri = PhotoSaveResult[0];
//打开文件
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
//base64字符串转成buffer
const decodeBuffer = buffer.from(trimQuotes(data), 'base64').buffer;
//写入文件
fs.writeSync(file.fd, decodeBuffer);
//关闭文件
fs.closeSync(file);
}).catch((err: Error) => {
console.error(err + '');
})
} catch (e) {
}
});
});
this.toggleExportPanel();
}
这段代码调用了核心函数getImageBase64FromCanvas,用于根据特效名在fabric画布中设置特效,并返回base64格式的处理完的图像,该函数的代码如下:
function getImageBase64FromCanvas(format) {
removeGridLines();
let dataURL = '';
switch (format) {
case 'svg':
// 使用 Fabric.js 的 toSVG 方法来获取 SVG 数据
dataURL = 'data:image/svg+xml,' + encodeURIComponent(canvas.toSVG());
break;
case 'png':
// 使用 Canvas 的 toDataURL 方法获取 PNG 图像的 base64 编码
dataURL = canvas.toDataURL('image/png');
break;
case 'jpg':
case 'jpeg':
// 使用 Canvas 的 toDataURL 方法获取 JPEG 图像的 base64 编码
dataURL = canvas.toDataURL('image/jpeg');
break;
case 'webp':
// 使用 Canvas 的 toDataURL 方法获取 WebP 图像的 base64 编码
dataURL = canvas.toDataURL('image/webp');
break;
default:
console.error('Unsupported format specified.');
break;
}
const base64Index = dataURL.indexOf('base64,') + 'base64,'.length;
addGridLines(gridSize, smallCellNumber, 'dashed');
return dataURL.substring(base64Index);
}
canvas.toDataURL
和 canvas.toSVG
函数详解
在这段代码中,这两个函数用于将 Canvas 画布的内容导出为不同格式的图像数据。以下是对这两个函数的详细介绍。
1. canvas.toDataURL
canvas.toDataURL
是 HTML5 Canvas 的一个方法,它用于将当前画布的内容导出为一个包含图像数据的 Base64 编码字符串。这个字符串通常以 data URL
的形式返回,可以直接在网页中使用,或者进一步处理。
语法:
dataURL = canvas.toDataURL(type, encoderOptions);
参数:
- type(可选):指定输出图像的格式。常用的格式包括:
'image/png'
:默认格式,输出 PNG 图像。'image/jpeg'
或'image/jpg'
:输出 JPEG 图像。'image/webp'
:输出 WebP 格式图像(某些浏览器可能不支持)。
- encoderOptions(可选):对于
'image/jpeg'
和'image/webp'
格式,可以指定一个介于0
和1
之间的数字,用于定义图像的质量。如果未指定,默认值为0.92
。
返回值:
canvas.toDataURL
返回一个data URL
,其格式类似于:data:image/png;base64,...
,后面的部分是图像的 Base64 编码。
使用示例:
// 获取 PNG 格式的 Base64 编码
let dataURL = canvas.toDataURL('image/png');
// 获取 JPEG 格式的 Base64 编码,图像质量为0.8
let dataURL = canvas.toDataURL('image/jpeg', 0.8);
应用场景:
- 图像保存:可以将图像数据保存为文件,或者通过上传接口将图像数据发送到服务器。
- 嵌入网页:将图像以 Base64 编码的形式嵌入到网页中,避免依赖外部图像文件。
- 即时显示:将图像的 Base64 编码用于
img
标签的src
属性,直接在网页上显示。
2. canvas.toSVG
canvas.toSVG
是 Fabric.js 提供的一个方法,用于将当前 Fabric.js 画布中的所有图形对象导出为 SVG 格式的字符串。SVG 是一种基于 XML 的矢量图形格式,支持无损缩放。
语法:
svgString = canvas.toSVG(options);
参数:
- options(可选):一个包含选项的对象,可以用来定制导出的 SVG 格式。例如:
- suppressPreamble:如果设置为
true
,将不会生成<?xml version="1.0" standalone="no" ?>
和<!DOCTYPE svg PUBLIC ...>
这些前导信息。 - viewBox:指定导出的 SVG 的 viewBox 属性,用于控制 SVG 图像的显示区域。
- suppressPreamble:如果设置为
返回值:
canvas.toSVG
返回一个包含 SVG 图像数据的字符串,这个字符串可以直接用于网页中,也可以保存为.svg
文件。
使用示例:
// 获取 Fabric.js 画布的 SVG 数据
let svgData = canvas.toSVG();
// 将 SVG 数据作为文件保存
let blob = new Blob([svgData], { type: 'image/svg+xml' });
应用场景:
- 矢量图形保存:保存为 SVG 格式,可以保持图像的可编辑性和无损缩放性。
- 嵌入网页:SVG 数据可以直接嵌入到 HTML 页面中,利用
<svg>
标签显示。 - 图形转换:可以将 Fabric.js 创建的复杂图形对象转换为 SVG 格式,以便在其他图形编辑器中进一步编辑或处理。
代码实现过程详解
在您的代码中,getImageBase64FromCanvas
函数根据用户指定的格式 (format
) 将 Canvas 画布内容导出为不同格式的 Base64 编码字符串,并返回纯粹的 Base64 部分。
-
函数开始:
removeGridLines()
:在导出图像之前,可能需要去掉一些辅助的网格线,以免它们出现在最终图像中。
-
格式判断:
- SVG 格式:
- 使用
canvas.toSVG()
获取 SVG 格式的字符串,然后使用encodeURIComponent
对其进行编码,以确保字符串可以安全地嵌入在 URL 中。最终将 SVG 数据转换为data:image/svg+xml
的 URL 形式。
- 使用
- PNG 格式:
- 使用
canvas.toDataURL('image/png')
获取 PNG 格式的 Base64 编码字符串。这个方法直接返回图像的 Base64 数据,可以进一步处理或展示。
- 使用
- JPEG/JPG 格式:
- 使用
canvas.toDataURL('image/jpeg')
获取 JPEG 格式的 Base64 编码字符串。这个格式适合用来压缩照片类型的图像,减少文件大小。
- 使用
- WebP 格式:
- 使用
canvas.toDataURL('image/webp')
获取 WebP 格式的 Base64 编码字符串。这种格式在提供高质量图像的同时具有更高的压缩效率。
- 使用
- SVG 格式:
-
Base64 数据提取:
- 使用
dataURL.indexOf('base64,')
查找 Base64 数据部分的起始位置,并通过substring
方法提取纯粹的 Base64 编码部分。
- 使用
-
恢复原状态:
addGridLines(gridSize, smallCellNumber, 'dashed')
:导出图像后,可能需要恢复之前移除的网格线或其他辅助元素。
-
返回结果:
- 函数返回提取后的 Base64 编码字符串,可以进一步用于文件保存、图像显示或上传。
通过这些方法,您可以轻松地从 Canvas 或 Fabric.js 画布中导出图像,并以多种格式保存或展示。