Canvas 多端实现生成图片及保存功能

栏目: Html5 · 发布时间: 7年前

内容简介:在项目中需要实现生成图片并保存到本地的功能,其中包含网络图片及后端接口返回数据。 而本文开篇为

在项目中需要实现生成图片并保存到本地的功能,其中包含网络图片及后端接口返回数据。 而 canvas 作为 HTML5 中新增的标签,主要用于在网页实时生成图像,并且可以操作图像内容,故选取 canvas 画图方式进行实现是一个不错的选择,并且可以通过转化为图片格式,来实现图片的下载保存功能。

canvas的多端实现及对比

本文开篇为 canvas 多端实现的图文对比及基本使用方式,比较适合 canvas 入门。对于已经熟悉 canvas 的同学,也可以直接阅读后文关于 canvas 实现过程中遇到的一些问题,比如无法实现长按下载及 ios 中出现的图片被旋转的兼容性总结,希望能够对大家有所帮助~

Canvas 多端实现生成图片及保存功能

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 多端实现生成图片及保存功能》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Coding the Matrix

Coding the Matrix

Philip N. Klein / Newtonian Press / 2013-7-26 / $35.00

An engaging introduction to vectors and matrices and the algorithms that operate on them, intended for the student who knows how to program. Mathematical concepts and computational problems are motiva......一起来看看 《Coding the Matrix》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具