使用canvas对多图片拼合并导出图片的方法


Posted in HTML / CSS onAugust 28, 2018

先说下canvas绘图的基本方法,如下:

const myCanvas = document.createElement('canvas');
    myCanvas.width = 400;
    myCanvas.height = 400;
const ctx = myCanvas.getContext('2d');
const img = new Image();
img.src = "1.jpg";
//当图片加载完毕的时候在drawImage,否则可能图片还没有加载完毕
img.onload=()=>{
    ctx.drawImage(img, 0, 0, 100, 50);
}

语法:

drawImage(image, x, y)

以canvas上指定的坐标点开始,按照图像的原始尺寸大小绘制整个图像。

drawImage(image, x, y, width, height)

以canvas上指定的坐标点开始,以指定的大小(width和height)绘制整个图像,图像会自动缩放。

drawImage(image, imageX, imageY, imageWidth, imageHeight, x, y, width, height)

将指定图像的局部图像(以(imageX, imageY)为左上角、宽度为imageWidth、高度为imageHeight的矩形部分)绘制到canvas中以( x, y)为左上角坐标、宽度为width、高度为height的矩形区域中

这次多图拼合的业务场景是做不同内容的定制分享图片,用到的图片元素有,背景图片、外链图片、网站logo、定制生产的二维码图,需要解决的问题,都是在画布转图片输出时产出的。主要有3点:

1、图片的跨域问题;
2、绘制多图,造成的画布污染;
3、图片的大小;

首先图片的跨域问题,这个问题在网上已经有很多相关信息,解决办法如下:

img.setAttribute('crossOrigin', 'anonymous');

当解决完跨域问题后,在多图拼合导出后,出现了新的报错信息:

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted Canvases may not be exported.

我发现这个问题时,查看网上的资料,大多也是用上面的跨域方法解决的,可是我明显在我的业务场景里是不管用的。

通过对代码的排查,我发现,背景图+二维码图时,并不会报这个错误,如外链图片做了跨域处理,单独使用时,也不会报错。而logo图片都是本地的文件,显然不应该是跨域问题。

那么二维码图和背景图能够不出错的原因,应该在于二维码图片源是base64格式的。

于是,我试着将logo图使用画布导出base64格式,然后和背景图+二维码图进行拼合,导出时果然没再报错。

所有解决多图拼合导出时,Tainted Canvases的问题,应该是将图片元素做成base64的格式,就能够避免了。

因为我的业务场景中有外链图片,而且不是所有的外链都对我网站域名做了跨域允许的处理,所以,在生成外链图片的base64数据时,可是使用img.onerror事件的处理,用缺省图替换。

因为有在画总图之前,有对多图的分别处理,因此,使用Promise处理可能会更好一些。

在图片导出的大小问题上,导出时尽量使用

myCanvas.toDataURL('image/jpeg', encoderOptions)

encoderOptions:可以从0到1的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。

以上个人对canvas拼合多图并导出图片的经验总结。 希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3轻松实现圆角效果
Nov 09 HTML / CSS
CSS3实战第一波 让我们尽情的圆角吧
Aug 27 HTML / CSS
CSS3 flex布局之快速实现BorderLayout布局
Dec 03 HTML / CSS
CSS3制作缩略图的详细过程
Jul 08 HTML / CSS
CSS3模拟IOS滑动开关效果
Sep 28 HTML / CSS
CSS3中新增的对文本和字体的设置
Feb 03 HTML / CSS
html5应用缓存_动力节点Java学院整理
Jul 13 HTML / CSS
简单介绍HTML5中的文件导入
May 08 HTML / CSS
HTML5新增属性data-*和js/jquery之间的交互及注意事项
Aug 08 HTML / CSS
html5.2 dialog简介详解
Feb 27 HTML / CSS
使用Html5多媒体实现微信语音功能
Jul 26 HTML / CSS
HTML5 新增内容和 API详解
Nov 17 HTML / CSS
HTML5 video 上传预览图片视频如何设置、预览视频某秒的海报帧
Aug 28 #HTML / CSS
HTML5 input新增type属性color颜色拾取器的实例代码
Aug 27 #HTML / CSS
html5中audio支持音频格式的解决方法
Aug 24 #HTML / CSS
HTML5实现音频和视频嵌入的方法
Aug 22 #HTML / CSS
canvas学习和滤镜实现代码
Aug 22 #HTML / CSS
详解html5 postMessage解决跨域通信的问题
Aug 17 #HTML / CSS
HTML5 manifest离线缓存的示例代码
Aug 08 #HTML / CSS
You might like
模仿OSO的论坛(五)
2006/10/09 PHP
非常好用的两个PHP函数 serialize()和unserialize()
2012/02/04 PHP
php+redis实现多台服务器内网存储session并读取示例
2017/01/12 PHP
php数据库的增删改查 php与javascript之间的交互
2017/08/31 PHP
js 页面关闭前的出现提示的实现代码
2011/05/25 Javascript
JQuery验证jsp页面属性是否为空(实例代码)
2013/11/08 Javascript
jquery小火箭返回顶部代码分享
2015/08/19 Javascript
为何JS操作的href都是javascript:void(0);呢
2015/11/12 Javascript
jQuery获取复选框被选中数量及判断选择值的方法详解
2016/05/25 Javascript
javascript判断firebug是否开启的方法
2016/11/23 Javascript
jQuery 插件实现随机自由弹跳气泡样式
2017/01/12 Javascript
ReactNative列表ListView的用法
2017/08/02 Javascript
React-intl 实现多语言的示例代码
2017/11/03 Javascript
vue设置动态请求地址的例子
2019/11/01 Javascript
解决Vue的项目使用Element ui 走马灯无法实现的问题
2020/08/03 Javascript
js实现简易ATM功能
2020/10/27 Javascript
关于Js中new操作符的作用详解
2021/02/21 Javascript
Python抓取Discuz!用户名脚本代码
2013/12/30 Python
在Python的Tornado框架中实现简单的在线代理的教程
2015/05/02 Python
解决Python 遍历字典时删除元素报异常的问题
2016/09/11 Python
对python3 urllib包与http包的使用详解
2018/05/10 Python
一个可以套路别人的python小程序实例代码
2019/04/09 Python
Python编写打字训练小程序
2019/09/26 Python
python模块和包的应用BASE_PATH使用解析
2019/12/14 Python
Python引入多个模块及包的概念过程解析
2020/09/21 Python
宝拉珍选澳大利亚官方购物网站:Paula’s Choice澳大利亚
2016/09/13 全球购物
团工委书记自荐书范文
2013/12/17 职场文书
岗位职责怎么写
2014/03/14 职场文书
会计人员岗位职责
2014/03/19 职场文书
村庄绿化方案
2014/05/07 职场文书
组织生活会表态发言材料
2014/10/17 职场文书
2014年调度员工作总结
2014/11/19 职场文书
项目技术负责人岗位职责
2015/04/13 职场文书
裁员通知
2015/04/25 职场文书
职工宿舍管理制度
2015/08/05 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书