h5 canvas 多张图片合成并保存到手机相册
需求:多张图片合成一张并下载
思路:
1.htmlDom转为canvas
2.toDataUrl() 可将canvas转为base64格式
3.创建a标签,利用a标签的download属性触发click事件,实现下载
先来用两张本地图片合成:
1 2 3 4 5 6 | data() { return { img1: require( '../../../assets/images/clock/111/he-bg.png' ), img2: require( '../../../assets/images/clock/111/timg.png' ), } }, |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | picTogether() { var bg =document.getElementById( "bg" ); var w = bg.width; var h = bg.height; var myImage = new Image(); //背景图片 你自己本地的图片或者在线图片 myImage.src = this .img1; myImage.setAttribute( 'crossOrigin' , 'anonymous' ); myImage.onload = ()=>{ var canvas = document.createElement( 'canvas' ); canvas.width = w; canvas.height = h; var ctx=canvas.getContext( "2d" ); ctx.drawImage(bg, 0, 0, ctx.canvas.width, ctx.canvas.height); var img= new Image(); img.src= this .img2; img.onload = () => { ctx.drawImage(img, 15, 120, ctx.canvas.width-30, ctx.canvas.height/2+100); this .downUpload( '海报.png' , canvas.toDataURL( "image/png" )); } } }, |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | downUpload(fileName,content) { let aLink = document.createElement( 'a' ); let blob = this .base64ToBlob(content); //new Blob([content]); let evt = document.createEvent( "HTMLEvents" ); //initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为 evt.initEvent( "click" , true , true ); aLink.download = fileName; aLink.href = URL.createObjectURL(blob); this .savePicHref(aLink.href) aLink.click() }, //base64转blob base64ToBlob(code) { let parts = code.split( ';base64,' ); let contentType = parts[0].split( ':' )[1]; let raw = window.atob(parts[1]); let rawLength = raw.length; let uInt8Array = new Uint8Array(rawLength); for ( let i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], {type: contentType}); }, |
两张本地图片合成和下载貌似做好了,如果图片换成用户上传的图片呢?如果不止两张图片呢?
如果是上传到服务器的图片,那么合成会存在跨域的问题,解决是把上传到服务器端图片下载到本地
1 2 3 4 5 | _downloadImg() { downloadImg({ "fileName" : this .fileName}).then(res =>{ this .upImg = res.datas.fileContent }) }, |
如果是多张图片合成,那么就一张张的画,也就是等图片onload成功后处理,这里用的是函数自调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | picTogether(){ var self = this ; var imgsrcArray = [ require( '../../../assets/images/clock/111/clock-day2.png' ), this .upImg, require( '../../../assets/images/clock/111/wenzi.png' ), require( '../../../assets/images/clock/111/bo1.png' ) ]; var bg =document.getElementById( "bg" ); var w = bg.width; var h = bg.height; var canvas = document.createElement( 'canvas' ); var ctx = canvas.getContext( '2d' ); canvas.width = w; canvas.height = h; var imglen = imgsrcArray.length; var drawimg = ( function f(n){ if (n < imglen){ var img = new Image(); img.crossOrigin = 'Anonymous' ; //解决跨域问题 img.onload = function (){ if (n == 0){ ctx.drawImage(img,0,0,ctx.canvas.width, ctx.canvas.height); } else if (n == 1){ ctx.drawImage(img,25,100,ctx.canvas.width-50,ctx.canvas.height-230); } else if (n==2){ ctx.drawImage(img,200,65,170,100); } else { ctx.drawImage(img,0,430,ctx.canvas.width,165); ctx.font= "16px Arial" ; ctx.fillText(`${self.fullName}`,20,480); ctx.fillStyle = "#A92E02" ; ctx.fillText(`连续打卡第 ${self.userInfo.num} 天`,20,505); } f(n+1); } img.src = imgsrcArray[n]; } else { self.downUpload( '海报.png' , canvas.toDataURL( "image/png" )); } })(0); }, |
到这里多张图片合成也做好了,也没有跨域问题了,pc端下载也没问题,
但是手机端去操作发现,保存图片没反应,相册也没有,
行不通,改变思路,用长按保存来做:
ios长按保存可以成功,查看相册也成功保存了合成的图片,
但是安卓手机,长按有菜单提示,但是保存的时候,提示“保存图片到手机失败”,查阅资料发现
安卓手机不支持blob格式的图片保存,
既然这种格式不支持,是不是其他格式可以支持呢?
答案是可以的。
可以把之前生成的base64格式转为jpg或png格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | downUpload(fileName,content) { this .downLoadImage(content) }, downLoadImage(content) { let form = new FormData() // FormData 对象 let bl = this .base64ToBlob(content) form.append( "file" , bl, "file_" + Date.parse( new Date())+ ".jpg" ) this ._postImg(form); },_postImg(file) { postImg(file).then(res => { let imgSrc = process.env.BASE_API + this .imgPathMid + res.datas[0].relativePath console.log(imgSrc) }) } |
这样手机端长按保存图片就可以了,ios和安卓都能保存。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!