原理:
通过 Canvas 处理图片,绘制后转成自己需要的格式进行下载
//创建Image和canvas
downloadImgH5(){
if (!process.env.VUE_APP_PLATFORM === 'h5') return
let imageUrl = '/img/xxx.png'
if (imgUrl.startsWith('/') || imgUrl.startsWith('./')) {
imgUrl = window.location.origin + imgUrl // 本地图片转换为完整URL
}
// 创建Image对象处理图片
const img = new Image()
img.src = imageUrl // 赋值
img.crossOrigin = "anonymous" // 处理跨域
img.onload = () => {
try {
// 创建Canvas
const canvas = document.createElement("canvas")
const ctx = canvas.getContext("2d")
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
// 将Canvas转换为Blob
canvas.toBlob((blob) => {
if (!blob) return console.error("图片处理失败:", error)
this.downloadFile(blob,imageUrl)
}, "image/png")
} catch (error) {
console.error("保存图片失败:", error)
}
}
img.onerror = (error) => {
console.error("图片加载失败:", error)
}
},
//下载方法
downloadFile(blob,imageUrl){
// 创建下载链接
const url = URL.createObjectURL(blob)
const a = document.createElement("a")
// 提取文件名
let fileName = "save_image"
const match = imageUrl.match(/[^/]+(?=\.)/)
if (match && match[0]) {
fileName = match[0]
}
a.download = `${fileName}.png`
a.href = url
// 模拟点击下载
document.body.appendChild(a)
a.click()
// 清理
document.body.removeChild(a)
URL.revokeObjectURL(url)
}
以上canvas除了可以将图片转成blob流,还可以将图片转成base64进行下载
//Canvas转DataURL并下载
downloadImgH5(){
...
img.onload = () => {
try {
// 创建Canvas
const canvas = document.createElement("canvas")
...
// 将Canvas转换为Blob
const dataURL = canvas.toDataURL('image/png')
// 创建下载链接
const link = document.createElement('a')
link.download = filename
...
} catch (error) {
console.error("保存图片失败:", error)
}
}
}
const dataURL = canvas.toDataURL('image/png')
总合两种下载方式:
1.转DataURL并下载
2.转Blob并下载
// Canvas转DataURL并下载
function downloadCanvasAsDataURL(canvas, filename = 'canvas-image.png') {
// 获取Base64格式的数据URL
const dataURL = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.download = filename;
link.href = dataURL;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
// Canvas转Blob并下载
function downloadCanvasAsBlob(canvas, filename = 'canvas-image.png') {
canvas.toBlob(blob => {
if (!blob) return;
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = filename;
link.href = url;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url); // 释放URL对象
}, 'image/png');
}
总结:
小型图像或简单场景,使用toDataURL()更简洁,base64比原始图像大 33% 左右;
大型图像或对性能有要求的场景,推荐使用toBlob(),blob与原始图像大小相近,且内存占比更低;
若是公众号内下载,a标签下载方式会被微信浏览器默认阻止,可以引导用户去浏览器下载,或者引导用户长按图片进行保存;
也可以对接微信 JS-SDK 调用微信下载图片接口
//初始化微信sdk
const wxConfig = {
debug: false, // 生产环境关闭debug
appId: 'wxXXXXXXXXXXXXXXX', // 你的公众号appId
timestamp: new Date().getTime(), // 时间戳
nonceStr: 'xxxxxxxxxxxxxx', // 随机字符串
signature: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // 签名
jsApiList: ['downloadImage', 'getLocalImgData'] // 需要使用的JS接口列表
}
// 配置微信JS-SDK
window.wx.config(wxConfig)
window.wx.ready(() => {
console.log('查看微信JS-SDK是否初始化成功')
})
let imageUrl = '/img/xxx.png'
// 调用微信下载图片接口
window.wx.downloadImage({
serverId: imgUrl, // 图片的URL
isShowProgressTips: 1, // 显示进度提示
success: (res) => {
console.log('图片下载成功', res);
// 保存到相册
window.wx.getLocalImgData({
localId: res.localId, // 图片的localId
success: (result) => {
console.log('图片已保存到相册')
},
fail: (err) => {
console.error('保存图片失败:', err);
//保存失败,请长按图片手动保存
}
})
},
fail: (err) => {
console.error('下载图片失败', err);
}
})
293

被折叠的 条评论
为什么被折叠?



