Canvas 图像处理之 getImageData

简介: 笔记

6.png在本文中,将简单介绍 <canvas> 的方法 getImageData ,并用其构建颜色选择器和兔年祝福粒子效果。为了简单并且快速看到效果,本文代码及效果将使用码上掘金

<canvas>元素用于生成图像。它本身就像一个画布,JavaScript 通过操作它的 API,在上面生成图像。它的底层是一个个像素,基本上<canvas>是一个可以用 JavaScript 操作的位图(bitmap)。

getImageData()方法用来读取<canvas>的内容,返回一个 ImageData 对象,包含了每个像素的信息,语法如下:

ctx.getImageData(sx, sy, sw, sh)

接受四个参数,分别是 sxsy是读取区域的左上角坐标,swsh是读取区域的宽度和高度。

getImageData() 返回的是一个ImageData对象,有三个属性:

  • ImageData.data:一个一维数组。该数组的值,依次是每个像素的红、绿、蓝、alpha 通道值(每个值的范围是 0~255),因此该数组的长度等于图像的像素宽度 x 图像的像素高度 x 4。这个数组不仅可读,而且可写,因此通过操作这个数组,就可以达到操作图像的目的。
  • ImageData.width:浮点数,表示 ImageData 的像素宽度。
  • ImageData.height:浮点数,表示 ImageData 的像素高度。


兔年祝福粒子效果


在过几天将迎来兔年,提前祝大家兔飞猛进!具体的步骤是编写HTML、CSS和JavaScript。使用 getImageData() 方法扫描图像获取像素信息,计算每个区域的相对亮度,创建一个简单的粒子系统,并根据粒子当前移动区域的亮度调整每个粒子的速度和不透明度。

这里使用的素材是一个很可爱的兔子形象,很生动。

image.png

颜色选择器


将在画布上绘制所有颜色。首先,需要添加一个画布标签来绘制颜色。将以下 HTML 添加到您的 HTML 中。

<div class="container">
  <h1>颜色选择器:Color Picker</h1>
</div>
<div class="container">
  <div class="color-picker"></div>
</div>

接下来,需要在画布上绘制所有颜色。要在画布上绘制颜色,需要获取画布的 contextwidthheight。这些变量将用于创建线性渐变和绘制矩形框。

1. 获取画布的 context、width、height

const [width, height] = [container.offsetWidth, container.offsetHeight];
[canvas.width, canvas.height] = [width, height];

2. 涂红、绿、蓝

在这里绘制没有透明度的颜色。例如红色,绿色,蓝色。下面是在一个框中绘制所有颜色的 Javascript 代码。

const gradientH = context.createLinearGradient(0, 0, width, 0);
gradientH.addColorStop(0, "rgb(255, 0, 0)"); // red
gradientH.addColorStop(1/6, "rgb(255, 255, 0)"); // yellow
gradientH.addColorStop(2/6, "rgb(0, 255, 0)"); // green
gradientH.addColorStop(3/6, "rgb(0, 255, 255)");
gradientH.addColorStop(4/6, "rgb(0, 0, 255)"); // blue
gradientH.addColorStop(5/6, "rgb(255, 0, 255)");
gradientH.addColorStop(1, "rgb(255, 0, 0)"); // red
context.fillStyle = gradientH;
context.fillRect(0, 0, width, height);

3.滤镜画布与线性梯度

接下来,会发现浅色和深色。例如,浅红色,深红色。为此将使用带有透明度的白色和黑色。这是使它变暗或变亮的 Javascript 代码。

const gradientV = context.createLinearGradient(0, 0, 0, height);
gradientV.addColorStop(0, "rgba(255, 255, 255, 1)"); // white
gradientV.addColorStop(0.5, "rgba(255, 255, 255, 0)");
gradientV.addColorStop(0.5, "rgba(0, 0, 0, 0)"); // transparent
gradientV.addColorStop(1, "rgba(0, 0, 0, 1)"); // black
context.fillStyle = gradientV;
context.fillRect(0, 0, width, height);
最后,当点击画布时,需要点击颜色。这里使用的技术是定位鼠标单击事件的 x/y 位置。然后,在 x/y 位置使用 getImageData 函数获取该位置的红色、绿色和蓝色值。
ini
复制代码
canvas.addEventListener('click', e => pickColor(e, canvas, circle, selected));
function pickColor(event, canvas, circle, selected) {
  const rect = event.target.getBoundingClientRect();
  const x = event.clientX - rect.left; 
  const y = event.clientY - rect.top;  
  const context = canvas.getContext('2d');
  const imgData = context.getImageData(x, y, 1, 1);
  const [r, g, b] = imgData.data;
  const [h, s, l] = rgb2hsl(r, g, b);
  const selectedColor = l < 0.5 ? '#FFF' : '#000';
  circle.style.top = (y - 6) + 'px';
  circle.style.left = (x - 6) + 'px';
  circle.style.borderColor = selectedColor;
  selected.innerText = Object.values(toCss(r,g,b,h,s,l))
    .toString().replace(/\)\,/g, ') ');
  selected.style.backgroundColor = toCss(r,g,b,h,s,l).hex;
  selected.style.color = selectedColor;
  canvas.dispatchEvent(new CustomEvent('color-selected', {
    bubbles: true,  detail: {r, g, b, h, s, l} 
  }));
}

完整代码如下:

image.png

总结


getImageData 常用的场景就是制作颜色选择器、像素粒子效果和图片的灰度。


相关文章
|
5月前
|
前端开发 JavaScript
canvas系列教程06 ——边界检测、碰撞检测
canvas系列教程06 ——边界检测、碰撞检测
57 2
|
5月前
|
前端开发
Canvas绘画之图像合成,图像层叠效果
Canvas绘画之图像合成,图像层叠效果
|
5月前
|
前端开发
Canvas绘画之简单的多边形绘画
Canvas绘画之简单的多边形绘画
|
5月前
|
前端开发
Canvas绘画之倒三角形,渐变色效果源码
Canvas绘画之倒三角形,渐变色效果源码
|
6月前
|
前端开发
canvas图像阴影处理
canvas图像阴影处理
|
6月前
|
算法 计算机视觉
图像处理之仿画笔效果一
图像处理之仿画笔效果一
27 0
|
7月前
|
前端开发 API
canvas详解03-绘制图像和视频
canvas详解03-绘制图像和视频
99 1
|
7月前
|
存储 前端开发
canvas详解05-变形
canvas详解05-变形
87 2
|
7月前
|
前端开发
canvas详解06-合成
canvas详解06-合成
68 2
|
存储 前端开发 算法
canvas 处理图像(下)
canvas 处理图像(下)
canvas 处理图像(下)