使用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动画事件—webkitAnimationEnd与计时器time事件
Jan 31 HTML / CSS
利用css3制作3D样式按钮实现代码
Mar 18 HTML / CSS
CSS3旋转——彩色扇子兼容firefox浏览器
Jun 04 HTML / CSS
浅谈CSS3 box-sizing 属性 有趣的盒模型
Apr 02 HTML / CSS
HTML5的Geolocation地理位置定位API使用教程
May 12 HTML / CSS
使用CSS实现弹性视频html5案例实践
Dec 26 HTML / CSS
基于Modernizr 让网站进行优雅降级的分析
Apr 21 HTML / CSS
HTML5 Canvas阴影使用方法实例演示
Aug 02 HTML / CSS
HTML5本地数据库基础操作详解
Apr 26 HTML / CSS
HTML5+WebSocket实现多文件同时上传的实例
Dec 29 HTML / CSS
萌新的HTML5 入门指南
Nov 06 HTML / CSS
Html5移动端div固定到底部实现底部导航条的几种方式
Mar 09 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
php 操作符与控制结构
2012/03/07 PHP
php数据结构与算法(PHP描述) 快速排序 quick sort
2012/06/21 PHP
浅析PHP中Collection 类的设计
2013/06/21 PHP
PHP实现更改hosts文件的方法示例
2017/08/08 PHP
php源码的安装方法和实例
2019/09/26 PHP
JavaScript 组件之旅(二)编码实现和算法
2009/10/28 Javascript
JavaScript之引用类型介绍
2012/08/10 Javascript
jQuery实现单行文字间歇向上滚动源代码
2013/06/02 Javascript
js控制浏览器全屏示例代码
2014/02/20 Javascript
javascript学习笔记(二)数组和对象部分
2014/09/30 Javascript
JS实现的网页倒计时数字时钟效果
2015/03/02 Javascript
JavaScript位移运算符(无符号) >>> 三个大于号 的使用方法详解
2016/03/31 Javascript
JQuery 动态生成Table表格实例代码
2016/12/02 Javascript
NodeJS爬虫实例之糗事百科
2017/12/14 NodeJs
vue使用技巧及vue项目中遇到的问题
2018/06/04 Javascript
JavaScript布尔运算符原理使用解析
2020/05/06 Javascript
vue实现井字棋游戏
2020/09/29 Javascript
Python数字图像处理之霍夫线变换实现详解
2018/01/12 Python
pandas DataFrame 警告(SettingWithCopyWarning)的解决
2019/07/23 Python
Django模板导入母版继承和自定义返回Html片段过程解析
2019/09/18 Python
利用django model save方法对未更改的字段依然进行了保存
2020/03/28 Python
浅谈Django中的QueryDict元素为数组的坑
2020/03/31 Python
Python关于拓扑排序知识点讲解
2021/01/04 Python
美国最大的家庭鞋类零售商之一:Shoe Carnival
2017/10/06 全球购物
美国户外服装和装备购物网站:Outland USA
2020/03/22 全球购物
Java TransactionAPI (JTA) 主要包含几部分
2012/12/07 面试题
点菜员岗位职责范本
2014/02/14 职场文书
学习演讲稿范文
2014/05/10 职场文书
民族学专业大学生职业规划范文:清晰未来的构想
2014/09/20 职场文书
2014年最新领导班子整改方案
2014/09/27 职场文书
2015年复活节活动总结
2015/02/27 职场文书
英语教师求职信范文
2015/03/20 职场文书
音乐课《小猫钓鱼》教学反思
2016/02/18 职场文书
Python进度条的使用
2021/05/17 Python
python 办公自动化——基于pyqt5和openpyxl统计符合要求的名单
2021/05/25 Python
mysql的Buffer Pool存储及原理
2022/04/02 MySQL