内容简介:在项目中需要实现生成图片并保存到本地的功能,其中包含网络图片及后端接口返回数据。 而本文开篇为
在项目中需要实现生成图片并保存到本地的功能,其中包含网络图片及后端接口返回数据。 而 canvas
作为 HTML5
中新增的标签,主要用于在网页实时生成图像,并且可以操作图像内容,故选取 canvas
画图方式进行实现是一个不错的选择,并且可以通过转化为图片格式,来实现图片的下载保存功能。
canvas的多端实现及对比
本文开篇为 canvas
多端实现的图文对比及基本使用方式,比较适合 canvas
入门。对于已经熟悉 canvas
的同学,也可以直接阅读后文关于 canvas
实现过程中遇到的一些问题,比如无法实现长按下载及 ios
中出现的图片被旋转的兼容性总结,希望能够对大家有所帮助~
canvas在H5中的实现
项目架构采用vue.js单页面应用。主要实现过程是通过 <canvas>
进行绘图,并转换成 <img>
标签展示,以此实现长按下载功能。
-
创建canvas标签
由于要对图片实现长按保存, canvas
标签无法直接实现,而后文将采用 img
标签进行覆盖以实现该功能。故此处将 canvas
样式设置为 display:none
进行隐藏。
-
getContext() 方法获得渲染上下文和它的绘画功能
注意此处创建 canvas
绘图上下文要在 mounted
函数中创建,即页面完成挂载之后执行,否则会报无法读取未定义属性 getContext
的错误。 getContext()
只有一个参数:上下文的格式,此处为 2D
图像。
-
引入图像到 canvas
-
通过
newImage()
获得一个指向HTMLImageElement
的对象 -
img.setAttribute('crossOrigin','anonymous')
解决跨域问题 -
img.src
设置图片源地址 -
使用
drawImage()
函数将图片绘制到canvas
画布上
图片加载是异步的,若调用 drawImage()
时图片没加载完那画布上就会是空的,用 onload
事件保证不会在加载完毕之前使用这个图片。
-
将 canvas 转换成图片格式
此时可以得到以 base64
编码的 base64Url
,参数 type
指定图片类型,如果指定的类型不被支持则以默认值 image/png
替代; encoderOptions
可以设置图片质量。
-
实现保存图片到本地
将返回的 base64Url
赋值给 <img>
标签的 src
属性,即可将绘制完成的图像以 <img>
标签展示出来。
使用上述方式通常可以直接实现长按下载并保存至本地。但在安卓系统中,却可能存在app 中不支持直接长按保存以 base64
格式展示的图片的情况,故本文第二部分便针对该问题进行了实现。
canvas在小程序端的实现
canvas是小程序的原生组件,使用时需注意相关限制。其实现思路虽与H5中大致相同,但由于小程序封装了自身的api,故本文对其进行了相应分析与总结。基本实现方式如下:
-
创建canvas标签,此处需指定canvas-id作为canvas 组件的唯一标识符
-
创建 canvas 绘图上下文
使用 wx.createCanvasContext
方法创建 canvas
绘图上下文,返回 CanvasContext
是小程序内建的一个对象,包含了一些绘图的方法可供使用。
-
引入图像及文字到 canvas
由于小程序本身不支持在手机端用 canvas
绘制在线图片,所以需要把图片的在线地址换成本地路径,然后再用本地路径去进行 canvas
绘制。
-
使用
wx.getImageInfo()
获取图片信息,返回图片本地路径(即下载一个网络图片到本地,同时需先配置download
域名才能生效) -
使用
drawImage()
方法绘制图像到画布 -
必须使用
draw()
方法将绘图上下文中的描述绘制上去,否则页面将为空
-
将canvas 转换成图片格式
wx.canvasToTempFilePath()
方法把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。
-
保存图片到系统相册
使用 wx.saveImageToPhotosAlbum()
保存图片到系统相册,需要用户授权 scope.writePhotosAlbum
。其中参数 filePath
是图片文件路径,可以是临时文件路径也可以是永久文件路径,注意不支持网络图片路径。
小结:无论是 H5 中的 toDataURL()
方法还是小程序中的 canvasToTempFilePath()
方法,都需要在图片加载完成后执行,否则页面将会呈现空白。由于我们无法精准得到图片完成加载的时长,故此处最好添加回调或使用 promise
对象,以确保后续处理任务(比如传递到其他服务器或保存相册)成功执行。
canvas 实现中遇到的问题
图片无法长按保存问题
在一般的开发中, canvas
标签虽没有像小程序这样可直接实现保存至相册的方法,但却可以通过转换成 <img>
标签进行展示,通过长按下载来保存至相册。但安卓手机在某些 app 中却存在不支持直接长按保存以 base64
格式展示的图片的情况。故针对这种情况本文将 base64
数据适当处理,并通过后端返回图片地址来实现长按保存图片至本地功能。
-
由于后端上传接口又大多接收文件格式的数据,此处首先将
base64
格式转换成blob
格式:
-
然后添加至
FarmData
对象并传输后端,通过将返回的url
数据赋值给img
标签的src
属性机箱展示,即可实现长按下载保存功能
ios拍摄的图片被旋转问题
当绘制的 canvas
图片中包含本地拍照上传的图片时,那么又会出现一个新的问题,如果使用本地拍照功能, ios
会针对横竖屏拍照进行处理, ios
竖屏拍照上传的照片,在安卓系统下显示会被旋转90度,故此时可以采用 canvas
对特定图片进行旋转解决方式。
-
首先获取 ios 拍照信息
判断当前系统是否为 ios
,如果是的话此处可通过采用 exif-js
插件来读取图像的原始数据,以获取拍照方向。
-
针对ios竖屏拍照,即拍摄方向属性
Orientation=6
时,可应用canvas
的rotate()
方法将其旋转90度,再后续对图片进行保存处理
总结
本文分别从 canvas
的多端实现及 canvas
使用过程中遇到的一些问题进行了总结,如果你还没有入门 canvas
的话,也许能从本文对 canvas
有个初步了解,并希望可以获得些许帮助。而 canvas
的深入使用还有很多地方值得探索,希望大家多多尝试并提出宝贵意见。当然,我们的公众号里有更多小哥哥小姐姐带来的前言技术文章,关注走起!~~
以上所述就是小编给大家介绍的《Canvas 多端实现生成图片及保存功能》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- itchat 保存好友信息以及生成好友头像图片墙
- 微信小程序--通过canvas生成图片并保存到本地
- ruby-on-rails – 如何保存ruby builder生成的xml而不是在rails应用程序中呈现它?
- 保存和恢复模型
- Android 文件保存
- 通过按钮单击保存PhpSpreadSheet
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Base64 编码/解码
Base64 编码/解码
正则表达式在线测试
正则表达式在线测试