上海WEB培训
达内上海市场营销中心

15026646813

热门课程

Web工程师训练陷阱:canvas 图片合成中的坑

  • 时间:2018-06-29 19:08
  • 发布:达内上海Web培训官方首页
  • 来源:企业面试题

一个优秀的编辑不会错过分享每一篇高质量原创,一名优秀Web工程师不会摒弃每一种大咖总结的技术经验。这里上海Web培训机构达内小编分享一篇来自lion1ou.win的文章:canvas 图片合成中的坑,希望能给大家一些提醒。

需求

要用代码来实现多张外部图片和文字的合并而且要上传到七牛云,再将图片链接通过客户端分享出去。图片背景需要支持用户自定义更换。

实现方案

在一个canvas上多次调用drawImage函数,分别绘制在canvas中,多次之后canvas中是多个图片合并的效果,然后再调用toDataURL函数将canvas转成dataURL格式的图片,再将dataURL格式装换为blob文件,上传至七牛云。

需要注意的坑

canvas图片合成模糊的问题

将canvas的长宽设为样式长宽的2倍或更大, 如下:

var canvas = document.getElementById("myCanvas");

canvas.width = "600";

canvas.height = "600"

canvas.style.height = "300px"

canvas.style.height = "300px"

报安全性错误

如果你的图片url和页面不在同一域下,在调用toDataURL函数的时候就会报安全性错误。chrome中:

Uncaught SecurityError: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.

Safari中貌似更严格,根域名相同子域不同依然会报错:

Cross-origin image load denied by Cross-Origin Resource Sharing policy.

原因:

上海Web培训机构小编觉得分析问题出现的原因胜过作对任何成功的案例,这一点是canvas 图片合成重中之重。没有CORS授权虽然可以在 canvas 中使用图像, 但这样做就会污染(taints)画布。 只要 canvas 被污染, 就不能再从画布中提取数据, 也就是说不能再调用 toBlob(), toDataURL() 和 getImageData() 等方法, 否则会抛出安全错误(security error).这实际上是为了保护用户的个人信息,避免未经许可就从远程web站点加载用户的图像信息,造成隐私泄漏。

解决方法:

这里上海Web培训机构觉得是重点部分,所以也带了代码。为每个图片创建一个新的img对象,再赋给其src等参数,用这种方式要等到img加载完毕再进行canvas其他操作,在img的load事件处理函数中进行操作,否则可能会绘制出空内容。

let img = new Image()

img.setAttribute('crossorigin', 'anonymous')

img.src = imgUrl

img.onload = function () {

// do Something

}

img.error = function () {}

canvas 图片合成,在mac和pc的浏览器上运行正常,但是在ios11以下的手机内无法toDataURL

解决办法1:

改变图片的载入方式,先在DOM上新建img标签,如下:

注意:crossOrigin="Anonymous"一定要在src属性前面

利用js获取img元素

var img = document.getElementById('bgImg')

ctx.drawImage(img, 0, 0, 700, 700)

canvas.toBlob() safari上无效

解决办法2:

将canvas使用toDataURL方法转为base64,再将base64通过file API 转为 blob

function dataURLtoBlob (dataurl) { // 将dataUrl 转为 Blob

let arr = dataurl.split(',')

let mime = arr[0].match(/:(.*?);/)[1]

let bstr = atob(arr[1])

let n = bstr.length

let u8arr = new Uint8Array(n)

while (n--) {

u8arr[n] = bstr.charCodeAt(n)

}

return new Blob([u8arr], {type: mime})

}var resultBase64 = canvas.toDataURL('image/jpeg') // 转为jpeg压缩图片大小var canvasBlob = dataURLtoBlob(resultBase64)

学习使我们处于不败之地,IT学习更能让我们适应互联网+大数据时代的高速发展,上海达内带你一同走进魔都的高薪阶层,做更有价值的事。【上海Web培训机构】达内

上一篇:会这些的人都做了前端开发工程师
下一篇:来自一位Web大牛口中的工程师常见面试题

一位前端老程序员无法忘怀的百度电话面试

上海Web开发培训:简单的SWING图形用户界面

来自一位Web大牛口中的工程师常见面试题

Web工程师训练陷阱:canvas 图片合成中的坑

选择城市和中心
贵州省

广西省

海南省

免费学习5天VIP课程