You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Uint8ClampedArray typed array represents an array of 8-bit unsigned integers clamped to 0-255; if you specified a value that is out of the range of [0,255], 0 or 255 will be set instead; if you specify a non-integer, the nearest integer will be set. The contents are initialized to 0.
The CanvasRenderingContext2.createImageData() method of the Canvas 2D API creates a new, blank ImageData object with the specified dimensions. All of the pixels in the new object are transparent black.
The CanvasRenderingContext2D.putImageData() method of the Canvas 2D API paints data from the given ImageData object onto the bitmap. If a dirty rectangle is provided, only the pixels from that rectangle are painted. This method is not affected by the canvas transformation matrix.
翻译:
CanvasRenderingContext2D.putImageData() 方法作为canvas 2D API 以给定的ImageData对象绘制数据进位图。如果提供了脏矩形,将只有矩形的像素会被绘制。这个方法不会影响canvas的形变矩阵。
前言
接触canvas应该是在去年半次元做制品计划吧,想想也好久了,不过,那会儿每天累得和狗一样,周末还要上课。经验总结也基本都记录在OneNote,思维跳跃性的记录也就不适合作为博客发布。
现在来了新公司,一段时间忙,一段时间闲成狗,所以就会再重新总结,写写博客。
canvas简介
我认为canvas最好的教程就是MDN的,canvas基础补充请戳这里>>
canvas绘制图片——drawImage
我们可以将已经加载好的图片画到canvas上。
绘制图片的api接口:
drawImage(image, x, y, width, height)
其中 image 是 image 或者 canvas 对象,x 和 y 是其在目标 canvas 里的起始坐标。width 和 height,这两个参数用来控制 当像canvas画入时应该缩放的大小。
drawImage其实还有四个额外参数,一般用来做截图,这里因为文章不涉及就不赘述了。有兴趣的小伙伴可以戳这里>>
获取canvas所有的像素点——getImageData
getImageData是canvas提供的一个非常强大的接口,它可以获取canvas的所有的像素点的值。不过,值的展现形式和一般的rgba或rgb等属性不同,所有的值会被记录在一个
Uint8ClampedArray
的一维数组里面。知识补充——Uint8ClampedArray
翻译一下:
那么问题来了,数组是怎么存每个像素点的rgba值的呢?
见图:
如果,canvas将每个像素点的值按照rgba这样的顺序一个一个的存入Unit8ClampedArray里面。
因此,数组的长度为length = canvas.width * canvas.height * 4。
知道了这种关系,我们不妨把这个一维数组想象成二维数组,想象它是一个平面图,如图:
一个格子代表一个像素
w = 图像宽度
h = 图像高度
这样,我们可以很容易得到点(x, y)在一维数组中对应的位置。我们想一想,点(1, 1)坐标对应的是数组下标为0,点(2, 1)对应的是数组下标4,假设图像宽度为2*2,那么点(1,2)对应下标就是
index=((2 - 1)*w + (1 - 1))*4 = 8
。推导出公式:index = [(y - 1) * w + (x - 1) ] * 4
知识补充
我们既然已经能够拿到图像的每一个像素点,那么我们就可以为所欲为啦!
不过客官别急,我们还有点小知识要补充,避免代码实现的过程陷入迷茫~
知识补充——createImageData
翻译(非直译):
我们会用到
ctx.createImageData(width, height)
这个接口,width和height是新ImageData对象的初始长宽。ImageData又是啥?
ImageData是一个对象,其实我们在canvas.getImageData拿到的对象就是ImageData,它内部由width,height,Uint8ClampedArray组成,
如:
{data: Uint8ClampedArray(958400), width: 400, height: 599}
知识补充——createImageData
翻译:
看上去有点迷糊,矩阵都出来了。不过不用担心,我们只关注第一句就好,忽略“如果“之后的文字。
我们将会用到
ctx.putImageData(imagedata, dx, dy)
接口,imageData就是用户提供的ImageData对象,dx和dy分别是canvas坐标系的x点和y点,将从这个(dx,dy)开始输入数据。实现滤镜
终于迎来了最后的阶段!
直接上代码:
html:
js
通过对imageData的处理,我们可以控制每个像素点,然后你想处理出不同的效果,只需要改写weird方法就可以了。我写了5种滤镜效果,效果如下gif图:
完整的项目地址在这里>>>
The text was updated successfully, but these errors were encountered: