Canvas是H5中新增的技术,主要运用在图片的处理和动画的绘制上,随着Canvas的使用场景愈来愈多,了解Canvas对平时开发大有裨益,这篇文章将介绍Canvas基本图片操做与处理html
将图片上传并绘制到Canva中是最多见的Canvas的图片处理,这个上传与绘制的过程是怎么实现的呢?下面举个例子:canvas
<canvas id="myCanvas"></canvas> <input type="file" id="file">
let upload = document.getElementById('file') upload.onchange = (event) => { let file = event.target.files[0] let fileReader = new FileReader() fileReader.onload = (e) => { let img = new Image() img.src = e.target.result img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.drawImage(img, 0, 0) } } fileReader.readAsDataURL(file) }
这个上传与绘制的过程能够总结为两步:api
这里为何要将base64格式的地址复制给Image对象,而后再将Image对象绘制到Canvas上而不是直接绘制呢?
这是由于Canvas上绘制时并不支持url做为图片源,Canvas只支持下面几种图片源:跨域
Canvas在绘图时还有一个须要注意的点就是:Canvas在绘制不一样域名下的图片会出现跨域的错误,如图:
被污染的Canvas,其实就是由于图片跨域的问题的,这时须要两步走:服务器
简单示例代码:cors
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.drawImage(img, 0, 0) console.log(canvas.toDataURL('image/png', 1.0)) }
更多跨域相关内容能够看这里ide
Canvas中图片缩放的其实是经过画布的缩放来达到的,所以默认的缩放中心是在画布原点(0, 0),可是通常状况下咱们作缩放时都但愿图片中心是缩放中心,这里有两种办法能达到图片中心做为缩放中心的缩放效果,接下来分别来看这两种办法的示例:
第一种:wordpress
let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.translate(img.width / 2, img.height / 2) context.scale(0.5, 0.5) context.translate(-img.width / 2, -img.height / 2) context.drawImage(img, 0, 0, img.width, img.height)
第一种方法就是画布平移,先将画布原点移到图像中心,而后再作画布缩放,再将画布平移还原,最后绘制图片,此时绘制的图片就是以图片中心作的缩放函数
第二种:性能
let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') let paintWidth = img.width / 2 let paintHight = img.height / 2 let originX = 0 // 原图片X坐标 let originY = 0 // 原图片Y坐标 let paintX = originX + (img.width - paintWidth) / 2 // 缩放后的图片X坐标 let paintY = originY + (img.height - paintHight) / 2 // 缩放后的图片Y坐标 context.drawImage(img, paintX, paintY, paintWidth, paintHight)
第二种就是最直接的计算当图片以左上角做为缩放中心,缩放后的图片位置产生的位置偏移,将位置偏移加上在进行图片绘制
Canvas的图片旋转和图片缩放同样,默认的旋转中心也是画布的原点(0, 0),此时也须要平移画布来实现图片的中心旋转,举个例子
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.translate(img.width / 2, img.height / 2) context.rotate(30 * Math.PI / 180) context.translate(-img.width / 2, -img.height / 2) context.drawImage(img, 0, 0, img.width, img.height) }
镜像变换能够以图片垂直中线为对称轴,左右镜像的变换叫水平镜像,或者水平中线为对称轴,上下镜像的变换叫垂直镜像,通常水平镜像用的比较多,这里就来看一个水平镜像的例子:
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.translate(img.width / 2, img.height / 2) context.scale(-1 , 1) context.translate(-img.width / 2, -img.height / 2) context.drawImage(img, 0, 0, img.width, img.height) }
原图:
水平镜像:
镜像操做的原理其实很简单:就是将scale设置为负值,当x轴的缩放为负值时,就是水平镜像,当y轴的缩放为负值时就是垂直镜像
对称轴翻转指的是图片沿着左上角至右下角的对角线翻转,来看用代码Canvas是怎么实现的:
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.translate(img.width / 2, img.height / 2) context.scale(-1 , 1) context.rotate(90 * Math.PI / 180) context.translate(-img.width / 2, -img.height / 2) context.drawImage(img, 0, 0, img.width, img.height) }
翻转图:
实现原理:先作水平镜像,而后顺时针旋转90度,因为先作的水平镜像,坐标轴会被水平翻转,顺时针旋转90度实际是逆时针旋转90度
图片的灰度效果是Canvas很是常见的一个图片处理效果,先来看实现灰度效果的代码:
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.drawImage(img, 0, 0, img.width, img.height) let imageData = context.getImageData(0, 0, img.width, img.height) let data = imageData.data for (let i = 0; i < data.length; i += 4) { let average = (data[i] + data[i + 1] + data[i + 2]) / 3 data[i] = average data[i + 1] = average data[i + 2] = average } context.putImageData(imageData, 0, 0) }
灰度效果图:
实现思路:
这里可能会有人对getImageData和putImageData这两个api不是很熟悉,想要了解这个两个api的能够点getImageDataputImageData
Canva在图片的处理上凸显的做用愈来愈大,所以写了这篇文章对Canvas基本图片操做与处理作了简单的介绍,但愿看了这篇文章对你们了解Canvas能有所帮助。若是有错误或不严谨的地方,欢迎批评指正,若是喜欢,欢迎点赞