gpt4 book ai didi

JavaScript 过滤器RGB

转载 作者:行者123 更新时间:2023-12-02 04:44:31 25 4
gpt4 key购买 nike

我目前正在将 Java 转换为 JavaScript,需要更改一些图像的颜色。

现在每个图像都在 Image 类中加载,图像如下所示:

Example image

它是一个作为字符集的PNG,发送的数据被映射到图像中的每个字符。

现有的 Java 代码如下所示:

class VDColorFilter extends RGBImageFilter
{
int fg;
int bg;
final int[] colors;

public VDColorFilter(final int fgc, final int bgc) {
super();
this.colors = new int[] { 0, 16711680, 65280, 16776960, 255, 16711935, 65535, 16777215 };
this.fg = fgc;
this.bg = bgc;
this.canFilterIndexColorModel = true;
}

public int filterRGB(final int x, final int y, int rgb) {
if (rgb == -1) {
rgb = (0xFF000000 | this.colors[this.bg]);
}
else if (rgb == -16777216) {
rgb = (0xFF000000 | this.colors[this.fg]);
}
return rgb;
}
}

我希望能够对我的图像执行同样的操作,但是是在 JavaScript 中。我对 Java 没有太多经验,因此我不确定 filterRGB 如何针对 colors 数组实际应用 RGB 结果。

当然,这只是对图像进行黑色着色,而不是白色。

有没有模仿这个的库?如果没有,达到相同结果的最佳方法是什么?

最佳答案

您可以使用 getImageData()putImageData() 过滤图像。这将需要实现跨域资源共享(CORS),例如图像来自与页面相同的服务器(浏览器中的安全机制)。

如果该部分没问题,让我们使用您的图像做一个示例 -

如果您的图像有 Alpha channel 而不是白色背景,那就最好了。这将允许您使用复合运算符直接更改颜色,而无需解析像素。

您可以通过两种方式执行此操作:

  1. 一劳永逸地去除背景,然后使用复合运算符(推荐)
  2. 用颜色替换所有黑色像素

使用第一种方法,您只需解析像素一次。每次需要更改颜色时,只需使用复合运算符(请参阅下面的演示 2)。

使用复合运算符

这里有一个方法,先打出背景。我们将为此使用无符号 32 位缓冲区,因为这比使用字节数组更快。

我们可以使用 View 的缓冲区来转换字节缓冲区并为其创建第二个 View :

var data32 = new Uint32Array(idata.data.buffer);

详细信息请参阅下面的代码:

var img = new Image();
img.crossOrigin = "";
img.onload = punchOut;
img.src = "//i.imgur.com/8NWz72w.png";

function punchOut() {

var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");

document.body.appendChild(this);
document.body.appendChild(canvas);

// set canvas size = image size
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;

// draw in image
ctx.drawImage(this, 0, 0);

// get pixel data
var idata = ctx.getImageData(0, 0, canvas.width, canvas.height),
data32 = new Uint32Array(idata.data.buffer), // create a uint32 buffer
i = 0, len = data32.length;

while(i < len) {
if (data32[i] !== 0xff000000) data32[i] = 0; // if not black, set transparent
i++
}

ctx.putImageData(idata, 0, 0); // put pixels back on canvas
}
body {background:#aaa}

现在我们有了透明图像,我们可以使用合成模式来改变它的颜色。我们需要使用的模式是“source-atop”:

var img = new Image();
img.crossOrigin = ""; img.onload = punchOut;
img.src = "//i.imgur.com/8NWz72w.png";
function punchOut() {
var canvas = document.querySelector("canvas"), ctx = canvas.getContext("2d");
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0);
var idata = ctx.getImageData(0, 0, canvas.width, canvas.height),
data32 = new Uint32Array(idata.data.buffer), i = 0, len = data32.length;
while(i < len) {if (data32[i] !== 0xff000000) data32[i] = 0; i++}
ctx.putImageData(idata, 0, 0);

// NEW PART --------------- (see previous demo for detail of the code above)

// alter color using composite mode
// This will replace existing non-transparent pixels with the next drawn object
ctx.globalCompositeOperation = "source-atop";

function setColor() {
for (var y = 0; y < 16; y++) {
for (var x = 0; x < 6; x++) {
var cw = (canvas.width - 1) / 6,
ch = (canvas.height - 1) / 16,
cx = cw * x,
cy = ch * y;

// set the desired color using fillStyle, here: using HSL just to make cycle
ctx.fillStyle = "hsl(" + (Math.random() * 360) + ", 100%, 80%)";

// fill the area with the new color, due to comp. mode only existing pixels
// will be changed
ctx.fillRect(cx+1, cy+1, cw-1, ch-1);
}
}
}
setInterval(setColor, 100);

// to reset comp. mode, use:
//ctx.globalCompositeOperation = "source-over";
}
body {background:#333}
<canvas></canvas>

最后,使用drawImage()根据每个字符的映射和单元格计算来选择每个字母(例如,请参阅我为您提供的关于drawImage用法的previous answer)。

  • 使用字符串定义字符映射
  • 使用 map 和 indexOf() 查找字母
  • 计算图像中 x 和 y 的映射索引
  • 使用 drawImage() 将该字母绘制到输出 Canvas 中的 x/y 位置

随机字母

var img = new Image();
img.crossOrigin = ""; img.onload = punchOut;
img.src = "http://i.imgur.com/8NWz72w.png";
function punchOut() {
var canvas = document.querySelector("canvas"), ctx = canvas.getContext("2d");
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0);
var idata = ctx.getImageData(0, 0, canvas.width, canvas.height),
data32 = new Uint32Array(idata.data.buffer), i = 0, len = data32.length;
while(i < len) {if (data32[i] !== 0xff000000) data32[i] = 0; i++}
ctx.putImageData(idata, 0, 0);
ctx.globalCompositeOperation = "source-atop";

function setColor() {
for (var y = 0; y < 16; y++) {
for (var x = 0; x < 6; x++) {
var cw = (canvas.width - 1) / 6,
ch = (canvas.height - 1) / 16,
cx = cw * x,
cy = ch * y;
ctx.fillStyle = "hsl(" + (Math.random() * 360) + ", 100%, 80%)";
ctx.fillRect(cx+1, cy+1, cw-1, ch-1);
}
}
}
setColor();

// NEW PART --------------- (see previous demo for detail of the code above)

var dcanvas = document.createElement("canvas"), xpos = 0;
ctx = dcanvas.getContext("2d");

document.body.appendChild(dcanvas);

for(var i = 0; i < 16; i++) {
var cw = (canvas.width - 1) / 6,
ch = (canvas.height - 1) / 16,
cx = cw * ((Math.random() * 6)|0), // random x
cy = ch * ((Math.random() * 16)|0); // random y
ctx.drawImage(canvas, cx+1, cy+1, cw-1, ch-1, xpos, 0, cw-1, ch-1);
xpos += 16;
}

}
body {background:#333}
<canvas></canvas>

关于JavaScript 过滤器RGB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29780446/

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