<!-- 页面结构 -->
<template>
<view>
<!-- 画布 -->
<canvas canvas-id="myCanvas" style="width: 690rpx;height: 668rpx;position: absolute;left: 100%;"></canvas>
<button type="warn" class="btn" @click="exportPost">保存海报</button>
</view>
</template>
<script>
export default {
data() {
return {
ctx: '',
img1Path: 'https://f0.0sm.com/node0/2024/04/86617AFD4CDD5399-405eaf169d20ee22.png', // 图片背景路径
img2Path: 'https://f0.0sm.com/node0/2024/04/86617AFED06414DC-b3ee7cb6d2a73d90.png', // 图片二维码路径
};
},
mounted() {
// 获取屏幕宽度比率
this.powerW = uni.getSystemInfoSync().windowWidth / 375;
// console.log(this.powerW, '宽度比率');
// 创建画布 初始化canvas上下文
this.ctx = uni.createCanvasContext('myCanvas');
},
methods: {
// 点击-保存海报
async exportPost() {
// 调用合并图片的方法。
this.mergeImages();
},
// 合并图片的方法
async mergeImages() {
// 加载第一张图片到canvas上
const image1 = await this.loadImage(this.img1Path);
// 在(0,0)位置绘制图片1,图一宽高分别为345px和334px
this.ctx.drawImage(image1, 0, 0, 345 * this.powerW, 334 * this.powerW);
// 加载第二张图片到canvas上,并设置位置和大小(根据需要调整)
const image2 = await this.loadImage(this.img2Path);
// 在(10,209)位置绘制图片2,图片二宽高75px,可以根据需要调整位置和大小
this.ctx.drawImage(image2, 10 * this.powerW, 209 * this.powerW, 75 * this.powerW, 75 * this.powerW);
// 设置字体样式
// this.ctx.font = '8px Arial';
this.ctx.font = `${(8 * this.powerW).toFixed(0)}px Arial`;
this.ctx.fillStyle = '#FFF2DF'; // 设置填充颜色
// 在 Canvas 上绘制文字
// 第二个和第三个参数是文字的 x 和 y 坐标
this.ctx.fillText('【ID:46545646445】', 10 * this.powerW, 296 * this.powerW);
// 完成绘制并导出为图片(可选)
this.ctx.draw(true, () => {
// 这里可以处理合并后的图片,比如保存到相册或上传到服务器等操作。
// 如果需要导出为文件或上传等操作,可以使用uni.canvasToTempFilePath等方法。
uni.canvasToTempFilePath({// res.tempFilePath临时路径
canvasId: 'myCanvas',
success: (res) => {
console.log(res, '临时路径');
uni.saveImageToPhotosAlbum({ // 保存本地
filePath: res.tempFilePath,
success: (response) => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
console.log(response, 'success');
},
fail: (response) => {
console.log(response, 'error');
uni.openSetting({ //打开权限
success: (response) => {
if (!response.authSetting['scope.writePhotosAlbum']){
uni.showToast({
title: '获取权限成功, 再次点击即可保存',
icon: none
})
} else {
uni.showToast({
title: '获取权限失败, 无法保存',
icon: none
})
}
}
})
}
})
}
})
});
},
// 注:canvas绘图在开发者工具上支持base64图片,在真机上是不可以的,
// 需让后台返回图片网络链接通过getimageinfo方法获取临时路径再进行操作
loadImage(src) {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: src, // 图片的URL或临时文件路径
success: (res) => {
console.log(res, 1.5);
// 获取图片的本地路径或临时文件路径,用于在canvas上绘制。
resolve(res.path);
},
fail: reject, // 处理加载失败的情况。
});
});
},
},
};
</script>
方法解析:
uni.getImageInfo({
src: src, // 图片的URL或临时文件路径
success: (res) => {
console.log(res, 1.5);
resolve(res.path); // 获取图片的本地路径或临时文件路径,用于在canvas上绘制。
},
fail: reject, // 处理加载失败的情况。
});
uni.getImageInfo(OBJECT)
获取图片信息。
小程序下获取网络图片信息需先配置download域名白名单才能生效。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
src | String | 是 | 图片的路径,可以是相对路径,临时文件路径,存储文件路径,网络图片路径 |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
参数名 | 类型 | 说明 | 平台差异说明 |
---|---|---|---|
width | Number | 图片宽度,单位px | |
height | Number | 图片高度,单位px | |
path | String | 返回图片的本地路径 | |
orientation | String | 返回图片的方向,有效值见下表 | App、小程序、京东小程序 |
type | String | 返回图片的格式 | App、小程序、京东小程序 |
orientation 参数说明
枚举值 | 说明 |
---|---|
up | 默认 |
down | 180度旋转 |
left | 逆时针旋转90度 |
right | 顺时针旋转90度 |
up-mirrored | 同up,但水平翻转 |
down-mirrored | 同down,但水平翻转 |
left-mirrored | 同left,但垂直翻转 |
right-mirrored | 同right,但垂直翻转 |
drawImage()方法
drawImage(image, x, y)
drawImage(image, x, y, width, height)
drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight,destX, destY, destWidth, destHeight)
参数 | 描述 |
---|---|
image | 所要绘制的图像。 这必须是表示<img>标记或屏幕外图像的Image对象,或者是Canvas元素。 |
x,y | 要绘制的图像的左上角位置。 |
width,height | 图像所应该绘制的尺寸。指定这些参数使得图像可以缩放。 |
sourceX,sourceY | 图像将要被绘制的区域的左上角,这些整数参数用图像像素来度量。 |
sourceWidth,sourceHeight | 图像所要绘制区域的大小,用图像像素表示。 |
destX,destY | 索要绘制的图像区域的左上角的画布坐标。 |
destWidth,destHeight | 图像区域所要绘制的画布大小。 |
fillText()方法--填充文字
ctx.fillText(text, x, y);
// 示例
// 在 Canvas 上绘制文字
// 第二个和第三个参数是文字的 x 和 y 坐标
this.ctx.fillText('【ID:46545646445】', 10 * this.powerW, 296 * this.powerW);
参数 | 描述 |
---|---|
text | 放置所填充的文字。 |
x | 文字所在位置的x坐标 |
y | 文字所在位置的y坐标 |
CanvasContext.draw(boolean reserve, function callback)
将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。
参数 | 描述 |
---|---|
boolean reserve | 本次绘制是否接着上一次绘制。 即 reserve 参数为 false,则在本次调用绘制之前 native 层会先清空画布再继续绘制; 若 reserve 参数为 true,则保留当前画布上的内容,本次调用 drawCanvas 绘制的内容覆盖在上面,默认 false。 |
function callback | 绘制完成后执行的回调函数。 |
uni.canvasToTempFilePath(object, component)
把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。在自定义组件下,第二个参数传入自定义组件实例,以操作组件内 <canvas>
组件。
object参数说明:
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
x | Number | 否 | 画布x轴起点(默认0) |
y | Number | 否 | 画布y轴起点(默认0) |
width | Number | 否 | 画布宽度(默认为canvas宽度-x) |
height | Number | 否 | 画布高度(默认为canvas高度-y) |
destWidth | Number | 否 | 输出图片宽度(默认为 width * 屏幕像素密度) |
destHeight | Number | 否 | 输出图片高度(默认为 height * 屏幕像素密度) |
canvasId | String | 是 | 画布标识,传入 <canvas/> 的 canvas-id(支付宝小程序是id、其他平台是canvas-id) |
fileType | String | 否 | 目标文件的类型,只支持 'jpg' 或 'png'。默认为 'png' |
quality | Number | 否 | 图片的质量,取值范围为 (0, 1],不在范围内时当作1.0处理 |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
uni.saveImageToPhotosAlbum(OBJECT)
保存图片到系统相册。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
filePath | String | 是 | 图片文件路径,可以是临时文件路径也可以是永久文件路径,不支持网络图片路径 |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
参数名 | 类型 | 说明 |
---|---|---|
path | String | 保存到相册的图片路径,仅 App 3.0.5+ 支持 |
errMsg | String | 调用结果 |
注意
- 可以通过用户授权API来判断用户是否给应用授予相册的访问权限uni.authorize(OBJECT) | uni-app官网
- H5没有API可触发保存到相册行为,下载图片时浏览器会询问图片存放地址。
- 微信小程序在2023年10月17日之后,使用API需要配置隐私协议
uni.openSetting(OBJECT)
调起客户端小程序设置界面,返回用户设置的操作结果。
平台差异说明
App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 抖音小程序、飞书小程序 | QQ小程序 | 快手小程序 | 京东小程序 |
---|---|---|---|---|---|---|---|---|
x | x | √ | √ | √ | √ | √ | √ | √ |
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数
属性 | 类型 | 说明 |
---|---|---|
authSetting | Object | 用户授权结果,其中 key 为 scope 值,value 为 Boolean 值,表示用户是否允许授权 |
uni.showToast(OBJECT)
显示消息提示框。
OBJECT参数说明
参数 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
title | String | 是 | 提示的内容,长度与 icon 取值有关。 | |
icon | String | 否 | 图标,有效值详见下方说明,默认:success。 | |
image | String | 否 | 自定义图标的本地路径(app端暂不支持gif) | App、H5、微信小程序、百度小程序、抖音小程序(2.62.0+) |
mask | Boolean | 否 | 是否显示透明蒙层,防止触摸穿透,默认:false | App、微信小程序、抖音小程序(2.47.0+) |
duration | Number | 否 | 提示的延迟时间,单位毫秒,默认:1500 | |
position | String | 否 | 纯文本轻提示显示位置,填写有效值后只有 title 属性生效,且不支持通过 uni.hideToast 隐藏。有效值详见下方说明。 | App |
success | Function | 否 | 接口调用成功的回调函数 | |
fail | Function | 否 | 接口调用失败的回调函数 | |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
icon 值说明
值 | 说明 | 平台差异说明 |
---|---|---|
success | 显示成功图标,此时 title 文本在小程序 平台最多显示 7 个汉字长度,App 仅支持单行显示。 | 支付宝小程序无长度无限制 |
error | 显示错误图标,此时 title 文本在小程序 平台最多显示 7 个汉字长度,App 仅支持单行显示。 | 支付宝小程序、快手小程序、抖音小程序、百度小程序、京东小程序、QQ小程序不支持 |
fail | 显示错误图标,此时 title 文本无长度显示。 | 支付宝小程序、抖音小程序 |
exception | 显示异常图标。此时 title 文本无长度显示。 | 支付宝小程序 |
loading | 显示加载图标,此时 title 文本在小程序 平台最多显示 7 个汉字长度。 | 支付宝小程序不支持 |
none | 不显示图标,此时 title 文本在小程序 最多可显示两行。 |