• 认真地记录技术中遇到的坑!

canvas图像保存

canvas 悠悠 10个月前 (03-02) 520次浏览 0个评论

通过前面的章节,我们能够在canvas画出各种炫酷多样的图形,但是这些画好的图像如何保存下一次使用呢?这篇文章将会探讨如何保存和加载canvas画布上的图像。

canvas画布上的图像

到目前为止,我们尚未深入了解Canvas画布真实像素的原理,事实上,canvas上面无论多么复杂的画,都是由有限个像素构成的,每个像素可以通过RGBA颜色值来描述。

只要知道了canvas画布上的所有像素点所包含的RGBA值信息,我们就能保存和重复利用它了。

所有这些像素数据信息可以通过ImageData对象操纵,直接读取或将数据数组写入该对象中。

ImageData 对象

说明

ImageData对象中存储着canvas对象真实的像素数据,它包含以下几个只读属性:

  • width图片宽度,单位是像素
  • height图片高度,单位是像素
  • data Uint8ClampedArray类型的一维数组,包含着RGBA格式的整型数据,范围在0至255之间

data属性是一个Uint8ClampedArray类型的一维数组,包含 width × height × 4 bytes数据,索引值从0到(高度×宽度×4)-1。

它可以被使用作为查看初始像素数据。每个像素用4个1bytes值(按照红,绿,蓝和透明值的顺序; 这就是”RGBA”格式) 来代表。每个颜色值部分用0至255来代表,每个部分被分配到一个在数组内连续的索引,左上角像素的红色部份在数组的索引0位置。像素从左到右被处理,然后往下,遍历整个数组。

Uint8ClampedArray类型

Uint8ClampedArray8位无符号整型固定数组) 类型化数组表示一个由值固定在0-255区间的8位无符号整型组成的数组;如果你指定一个在 [0,255] 区间外的值,它将被替换为0或255;如果你指定一个非整数,那么它将被设置为最接近它的整数。(数组)内容被初始化为0。一旦(数组)被创建,你可以使用对象的方法引用数组里的元素,或使用标准的数组索引语法(即使用方括号标记)。

可以使用Uint8ClampedArray.length属性来读取像素数组的大小(以bytes为单位)。

创建一个ImageData对象

可以使用createImageData()方法来创建ImageData对象,有下面两张形式:

  • createImageData(width, height)
  • createImageData(imagedata)

参数的含义如下:

  • width ImageData新对象的宽度
  • height ImageData新对象的高度
  • imagedata从现有的ImageData对象中,复制一个和其宽度和高度相同的对象。图像自身不允许被复制。

使用上面两种方法创建的ImageData对象的所有像素都会被预设为透明黑,并非复制了图片数据

从canvas获取ImageData对象

可以通过canvas获取到ImageData对象从而保存canvas画布的内容。方法如下:

getImageData(left, top, width, height)

这个方法会返回一个ImageData对象,它代表了画布区域的对象数据,此画布的四个角落分别表示为(left, top), (left + width, top), (left, top + height), 以及(left + width, top + height)四个点。这些坐标点被设定为画布坐标空间元素。

需要注意:任何在canvas画布以外的元素都会被返回成一个透明黑的ImageData对像。

一个颜色选择器的例子:

把鼠标放在图片上提取颜色

// 远程加载一张图片
var img = new Image();
img.src = 'https://asset.uusama.com/loli.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// 图片加载完成之后绘制在canvas上面
img.onload = function() {
  ctx.drawImage(img, 0, 0);
  img.style.display = 'none';
};

var color = document.getElementById('color');

// 提取颜色,并实施设置color的背景颜色
function pick(event) {
  // 获取光标当前坐标
  var x = event.layerX;
  var y = event.layerY;
  // 获取光标处的像素信息
  var pixel = ctx.getImageData(x, y, 1, 1);
  var data = pixel.data;
  var rgba = 'rgba(' + data[0] + ',' + data[1] +
             ',' + data[2] + ',' + (data[3] / 255) + ')';
  color.style.background =  rgba; // 设置color元素的背景色
  color.textContent = rgba; // 显示RGBA值
}
// 鼠标移动则提取颜色
canvas.addEventListener('mousemove', pick);

ImageData对象信息写入canvas

你可以用putImageData()方法去对场景进行像素数据的写入:

  • putImageData(myImageData, dx, dy)

dx和dy参数表示你希望在场景内左上角绘制的像素数据所得到的设备坐标。

例如,为了在场景内左上角绘制myImageData代表的图片,你可以写如下的代码:

ctx.putImageData(myImageData, 0, 0);

保存图片

HTMLCanvasElement提供一个toDataURL()方法,此方法在保存图片的时候非常有用。它返回一个包含被类型参数规定的图像表现格式的数据链接。返回的图片分辨率是96dpi。

  • canvas.toDataURL(type, encoderOptions)
    • type可选,图片格式,默认为 image/png
    • encoderOptions可选,在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略

当你从画布中生成了一个数据链接,例如,你可以将它用于任何元素,或者将它放在一个有download属性的超链接里用于保存到本地。

你也可以从画布中创建一个Blob对像,使用canvas.toBlob(callback, type, encoderOptions)方法。


转载请注明出处 canvas图像保存
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址