需求:使用canvas-2d绘制用户头像昵称,小程序码生成相应图片海报
异常:某些ios机型绘制保存后的图片为空白图片
手机型号:iphone8;系统版本:ios11.3 ;微信:7.0.15
手机型号:iPhone11 Pro Max;系统版本:13.2.3
手机型号:iPhoneX max ; ios:13.6 ;微信版本:7.0.15
api使用:wx.downloadFile;wx.canvasToTempFilePath;wx.saveImageToPhotosAlbum
wxml
<canvas style="position: absolute;top:0;left:100%;width: 750px;height: 1206px;" canvas-id='canvas'></canvas>
方法封装
const scopeName = {
"userInfo": "用户信息",
"userLocation": "地理位置",
"address": "通讯地址",
"invoiceTitle": "发票抬头",
"invoice": "发票",
"werun": "微信运动步数",
"record": "录音功能",
"writePhotosAlbum": "保存到相册",
"camera": "摄像头"
};
const authorize = (scope) => {
return new Promise((resolve, reject) => {
const failText = `须授权${scopeName[scope]}!`;
wx.getSetting({
success(res) {
if (res.authSetting[`scope.${scope}`]) {
resolve(true);
} else {
wx.authorize({
scope: `scope.${scope}`,
success() {
resolve(true);
},
fail() {
wx.showModal({
title: "提示",
content: `检测到未打开${scopeName[scope]}权限`,
confirmText: "授权",
success(res) {
if (res.confirm) {
wx.openSetting({
success(res) {
if (res.authSetting[`scope.${scope}`]) {
resolve(true);
} else {
reject(failText);
}
}
});
} else {
reject(failText);
}
},
fail() {
reject(failText)
}
});
},
});
}
},
fail() {
reject(failText);
}
});
});
};
const saveImageToPhotosAlbum = (filePath) => {
return new Promise((resolve, reject) => {
wx.saveImageToPhotosAlbum({
filePath,
success(res) {
resolve(res);
},
fail() {
reject();
},
});
});
};
const saveImage = (url, type = 'online') => {
return new Promise(async (resolve, reject) => {
const isAuth = await await authorize("writePhotosAlbum").catch(err => {
reject(err);
});
if (isAuth) {
let tempFilePath = url;
if (type === 'online') {
tempFilePath = await downloadFile(url).catch(err => {
reject('图片下载失败')
});
}
const val = await saveImageToPhotosAlbum(tempFilePath).catch(err => {
reject('取消保存');
})
if (val) {
resolve(true);
} else {
reject();
}
} else {
reject('无授权');
}
})
};
/**canvas保存图片 */
const canvasToTempFilePath = (params, component) => {
return new Promise((resolve, reject) => {
wx.canvasToTempFilePath({
...params,
success(res) {
resolve(res);
},
fail(res) {
reject();
},
}, component)
});
}
逻辑
/**获取海报 */
createPoster(bg, qrcode, avatar, nickName) {
return new Promise(async (resolve, reject) => {
if (!bg || !qrcode || !avatar) return reject('图片资源异常');
const ctx = wx.createCanvasContext("canvas", this); //获取画布
//画海报
ctx.drawImage(bg, 0, 0, 750, 1206);
//画小程序码
ctx.drawImage(qrcode, 466, 937, 202, 202);
//画昵称
ctx.font = '22px PingFangSC-Regular'
ctx.setFillStyle('#6C3511');
ctx.fillText(nickName, 198, 1000);
//画头像
const avatarInfo = {
space: 78,
x: 98,
y: 971
}
ctx.save();
ctx.beginPath();
ctx.arc(avatarInfo.x + avatarInfo.space / 2, avatarInfo.y + avatarInfo.space / 2, avatarInfo.space / 2, 0, Math.PI * 2, false);
ctx.clip();
ctx.drawImage(avatar, avatarInfo.x, avatarInfo.y, avatarInfo.space, avatarInfo.space);
ctx.restore();
ctx.draw();
const dpr = wx.getSystemInfoSync().pixelRatio || 1;
setTimeout(async () => {
const res = await canvasToTempFilePath({
x: 0,
y: 0,
width: 750 * dpr,
height: 1026 * dpr,
destWidth: 750 * dpr,
destHeight: 1206 * dpr,
canvasId: "canvas",
fileType: "jpg",
}, this);
if (res && res.tempFilePath) {
resolve(res.tempFilePath);
} else {
reject('画板异常');
}
}, 200)
});
},
async onShareImage() {
wx.showLoading({
title: '正在生成图片',
mask: true
});
try {
let bgData = "/assets/images/share/background.jpg";
const nickName="昵称";
const qrcodeUrl="";//二维码网络地址(已加入白名单)
const avatar="";//用户头像网络地址(已加入白名单)
const text = nickName.length > 10 ? `${nickName.substring(0,9)}...` : nickName;
const avatarData = await downloadFile(avatar); //头像
const qrcodeData = await downloadFile(qrcodeUrl); //小程序码数据
const posterData = await this.createPoster(bgData, qrcodeData, avatarData, text); //生成海报数据
const result = await saveImage(posterData, "file"); //保存图片
if (result) {
wx.hideLoading();
wx.showToast({
title: "图片已保存",
mask: true
});
}
} catch (error) {
wx.hideLoading();
wx.showToast({
icon: "none",
title: `分享图片生成失败!${error}`,
mask: true
});
}
},
代码不是canvas 2d。canvasToTempFilePath 需放到ctx.draw函数内,去看 wx.canvasToTempFilePath文档。。
遇到同样的问题,请问解决了吗?
请具体描述问题出现的流程,并提供能复现问题的简单代码片段https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html