前端如何使用canvas做图片处理

原创 前端工程师小鱼 随笔 前端 112阅读 2019-05-18 21:37:53 举报

),可以选的方案两个:

1、前端使用canvas做图片处理;

2、服务端引用图片处理的类库来做图片处理

两个方案都是可以实现的,但在页面上传图片,不需要存储图片处理结果且不需要兼容低浏览器的场景中,在前端做处理是更好的方案;若选择服务端处理不仅会涉及到图片的上传和下载,还会涉及到服务端对图片的存储和定时清理等等一系列问题,所以本文主要介绍如何使用canvas做图片处理–>打马赛克,理解这种图片处理的思路后,其他形式的图片处理原理也是一样的。

项目地址:https://github.com/saucxs/watermark-image 欢迎fork和star

测试工具的地址:https://www.mwcxs.top/static/testTool/image/index.html

二、图片打码

2.1思路分析

图片来源主要有两种,一种是直接使用图片URL,另一种是直接操作图片文件对象(File对象);但是无论哪一种方式,我们处理图片的原理都是一样的,主要是以下三个步骤:

1、创建Image对象对图片进行加载;

2、加载成功后,将图片写进canvas画布

3、最后在canvas画布取出图片的所有像素点,取出打码位置的RGB值来画马赛克即可

image

2.2代码实现

2.2.1创建Image对象对图片进行加载

首先我们要对图片来源分别进行处理,第一种使用图片的URL,如下:

第二种是图片File对象,File对象我们不能直接使用,需要借助URL.createObjectURL()方法将File对象转换成一个可用于图片src属性的新URL对象,这个URL对象值存储在程序内存中的,所以要在不需要使用这个URL对象时,需要手动调用URL.revokeObjectURL()方法来主动释放该内存。如下

注: 若需要获取图片像素或转成dataURL需设置Img的crossOrigin属性来处理跨域问题,即设置img.crossOrigin = ‘’。

2.2.2图片加载成功后,将图片写进canvas画布

将一张加载成功后的图片写进canvas画布非常简单,只需要三行代码即可

但以上代码是直接在页面的canvas元素上绘制图像的,若绘制的操作动作需要多次或反复进行,这样会导致浏览器实时不断渲染和绘制canvas元素所在的复合图层,这会在一定程度上影响页面的性能。

所以我们更好的方式是动态创建一个存储在程序内存的canvas元素,然后在该canvas元素上进行画图以及马赛克绘制等等的操作,所有操作完成后直接将结果一次性绘制到页面上的canvas元素上,可提高绘制性能;

2.2.3在动态画布上绘制马赛克

在动态canvas画布上绘制图像完成后,我们可使用canvas上下文的getImageData()方法获取该图像的所有像素点,如下

其中imageData.data就是图像的所有像素点,也就是我们最熟悉的RGBA值,是一个一维数组,类型为Uint8ClampedArray,数组内的所有数值都不会超过2的8次方,该像素点数组内四个数值(R, G, B, A)表示一个像素点,其中A只有两个值,0和255,分别表示透明度0和1,如下

image

那么我们可根据图片的宽高得出图像像素点一维数组的长度,即width * height * 4,那么下面我们即可操作图像像素点来画马赛克了,假设我们每个马赛克的大小为10px,如下

马赛克绘制完成后,再次调用canvas上下文的drawImage()方法将动态canvas画到页面上的canvas即可。

三、代码封装

将以上代码用面向对象的方式封装起来,实现在指定的区域打码以及画出线框,实现如下

3.1构造函数

3.2原型对象

3.3使用

四、总结

以上便是canvas图片处理思路以及代码实现,代码实现并不复杂。

处理的原理:1、创建image对象对图片进行加载;2、加载成功后,将图片写进canvas画布中;3、最后在canvas画布取出图片的所有像素点,取出打码位置的RGB值来操作其他的(比如画马赛克)

优化点:直接在页面的canvas元素上绘制图像,若绘制的操作需要多次或者反复进行,会导致浏览器实时不断的渲染和绘制canvas元素所在的复合图层,会影响页面性能,我们动态创建一个存储在内存的canvas元素,然后在该canvas上进行画图等操作,最后将操作结果一次性的绘制到页面的canvas元素上,提高绘制性能。

最后,给大家推荐一个前端学习进阶内推交流群685910553前端资料分享),不管你在地球哪个方位,
不管你参加工作几年都欢迎你的入驻!(群内会定期免费提供一些群主收藏的免费学习书籍资料以及整理好的面试题和答案文档!)

如果您对这个文章有任何异议,那么请在文章评论处写上你的评论。

如果您觉得这个文章有意思,那么请分享并转发,或者也可以关注一下表示您对我们文章的认可与鼓励。

愿大家都能在编程这条路,越走越远。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复