gpt4 book ai didi

html - 以灰度保存 Canvas

转载 作者:搜寻专家 更新时间:2023-10-31 02:25:37 26 4
gpt4 key购买 nike

我想知道是否可以在 HTML5 中使用彩色 Canvas ,然后在单击保存按钮时将其保存为黑白(灰度)PNG。我已经设法将 Canvas 保存为 PNG,太棒了!但我想添加灰度功能,而不必自己用 Illustrator 等程序更改它。顺便说一句, Canvas 上有移动的粒子。 (虽然我不确定这是否有任何影响)

谢谢~!

function download(){
var dt = c.toDataURL('image/png');
this.href = dt;
};
downloadlink.addEventListener('click', download, false);

最佳答案

可以通过从 Canvas 中提取 RGB 数据并计算它们的亮度值来实现。

不过,有几个先决条件需要满足,例如 CORS(在这种情况下这似乎不是问题,因为您已经可以保存图像)以及是否希望在保存后保留原始数据您可以将 Canvas 上的当前图像复制到临时图像,或者保留需要提取的像素数据的备份。

RGB 到亮度

根据REC 709(或BT.709)公式,将RGB数据转换为亮度值(灰色)的公式如下:

luma = Red x 0.2126 + Green x 0.7152 + Blue x 0.0722

或者,您可以改用 REC 601 (BT.601) 公式(这在标清视频素材中更为常见):

luma = Red x 0.299 + Green x 0.587 + Blue x 0.114

要使用它,只需遍历所有像素,使用这些公式之一获取亮度值,并将目标中的所有 channel 替换为生成的亮度值。

临时数据

对于临时数据,我们可以执行以下任一操作(单击保存按钮时):

临时 Canvas

  • 创建临时 Canvas
  • 设置大小等于源 Canvas
  • 使用 drawImage() 在源 Canvas 中绘制
  • 使用 getImageData() 提取目标 Canvas 的像素数据
  • 迭代像素,使用公式转换,放回数据
  • 保存图片然后丢弃临时 Canvas

图像数据备份

  • 使用 getImageData() 提取图像数据 - 这将作为我们的备份
  • 使用 createImageData() 创建相同大小的新 ImageData
  • 迭代备份中的像素,但将结果以亮度形式放入创建的 ImageData
  • 将创建的ImageData放回去,保存出图片
  • 放回备份数据

是否需要后一步实际上取决于您如何更新 Canvas 。如果您正在为循环制作动画,则可能不需要放回备份(或保留一个),如果一切都得到更新,但如果是这样并且您看到灰色闪烁或某些区域留下灰色,则需要此步骤。

使用ImageData方法的例子

var ctx = c.getContext("2d"), img = new Image;
img.onload = setup; img.crossOrigin = "";
img.src = "//i.imgur.com/OrYVGI8.jpg";

function setup() {
c.width = this.naturalWidth; c.height = this.naturalHeight;
ctx.drawImage(this, 0, 0); btn.disabled = false
}

// Main code for demo
btn.onclick = function() {

var idataSrc = ctx.getImageData(0, 0, c.width, c.height), // original
idataTrg = ctx.createImageData(c.width, c.height), // empty data
dataSrc = idataSrc.data, // reference the data itself
dataTrg = idataTrg.data,
len = dataSrc.length, i = 0, luma;

// convert by iterating over each pixel each representing RGBA
for(; i < len; i += 4) {
// calculate luma, here using Rec 709
luma = dataSrc[i] * 0.2126 + dataSrc[i+1] * 0.7152 + dataSrc[i+2] * 0.0722;

// update target's RGB using the same luma value for all channels
dataTrg[i] = dataTrg[i+1] = dataTrg[i+2] = luma;
dataTrg[i+3] = dataSrc[i+3]; // copy alpha
}

// put back luma data so we can save it as image
ctx.putImageData(idataTrg, 0, 0);
demo.src = c.toDataURL(); // set demo result's src url

// restore backup data
ctx.putImageData(idataSrc, 0, 0);
};
<button disabled id=btn>SAVE TO GREY</button> (click then scroll down to see result)<br>
<canvas id=c></canvas><br><img id=demo>

关于html - 以灰度保存 Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37159358/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com