gpt4 book ai didi

javascript - 为 HTML Canvas 创建自己的过滤器

转载 作者:太空宇宙 更新时间:2023-11-04 07:31:55 25 4
gpt4 key购买 nike

我想为 HTML Canvas 创建自己的过滤器。下面的代码。我得到错误:

Failed to execute 'putImageData' on 'CanvasRenderingContext2D': parameter 1 is not of type 'ImageData'

但是如果我改变return outputData;filter(input, values){} 的末尾与

for (let i = 0; i < outputData.length; i++){
inputData[i] = outputData[i];
}

一切正常,但我想,filter(input, values){}返回值。我该怎么做?

//////////////////////////////
// Distortion Filter //
// Originally by JoelBesada //
//////////////////////////////
class FilterDistortion {
constructor() {
this.name = 'Distortion';
this.defaultValues = {
size: 4,
density: 0.5,
mix: 0.5,
};
this.valueRanges = {
size: { min: 1, max: 10 },
density: { min: 0.0, max: 1.0 },
mix: { min: 0.0, max: 1.0 },
};
}

filter(input, values = this.defaultValues) {
const { width, height } = input;

const inputData = input.data;
const outputData = inputData.slice();

let size = (values.size === undefined)
? this.defaultValues.size
: parseInt(values.size, 10);
if (size < 1) size = 1;

const density = (values.density === undefined)
? this.defaultValues.density
: Number(values.density);

const mix = (values.mix === undefined)
? this.defaultValues.mix
: Number(values.mix);

const radius = size + 1;
const numShapes = parseInt(((((2 * density) / 30) * width) * height) / 2, 10);

for (let i = 0; i < numShapes; i++) {
const sx = (Math.random() * (2 ** 32) & 0x7fffffff) % width;
const sy = (Math.random() * (2 ** 32) & 0x7fffffff) % height;

const rgb2 = [
inputData[(((sy * width) + sx) * 4) + 0],
inputData[(((sy * width) + sx) * 4) + 1],
inputData[(((sy * width) + sx) * 4) + 2],
inputData[(((sy * width) + sx) * 4) + 3],
];

for (let x = sx - radius; x < sx + radius + 1; x++) {
for (let y = sy - radius; y < sy + radius + 1; y++) {
if (x >= 0 && x < width && y >= 0 && y < height) {
const rgb1 = [
outputData[(((y * width) + x) * 4) + 0],
outputData[(((y * width) + x) * 4) + 1],
outputData[(((y * width) + x) * 4) + 2],
outputData[(((y * width) + x) * 4) + 3],
];
const mixedRGB = this.mixColors(mix, rgb1, rgb2);

for (let k = 0; k < 3; k++) {
outputData[(((y * width) + x) * 4) + k] = mixedRGB[k];
}
}
}
}
}

return outputData;
}

linearInterpolate(t, a, b) {
return a + (t * (b - a));
}

mixColors(t, rgb1, rgb2) {
const r = this.linearInterpolate(t, rgb1[0], rgb2[0]);
const g = this.linearInterpolate(t, rgb1[1], rgb2[1]);
const b = this.linearInterpolate(t, rgb1[2], rgb2[2]);
const a = this.linearInterpolate(t, rgb1[3], rgb2[3]);

return [r, g, b, a];
}
}

/////////////////
// Driver Code //
/////////////////
var img = new Image(); img.onload = draw; img.src = "//i.imgur.com/Kzz84cr.png";
function draw() {
c.width = this.width; c.height = this.height;

var ctx = c.getContext("2d");
// main loop
ctx.drawImage(this, 0, 0); // draw video frame
var data = ctx.getImageData(0, 0, c.width, c.height);
ctx.putImageData(new FilterDistortion().filter(data), 0, 0);
ctx.globalCompositeOperation = "source-over"; // "reset"
// rinse, repeat
}
<canvas id=c></canvas>

最佳答案

错误消息说明了一切,您需要传递一个 ImageData作为 putImageData 的第一个参数。
这里你传递了一个 UInt8ClampedArray。

所以你要么创建一个 new ImageData从这个 TypedArray(当 ImageData 构造函数可用时),或到 create an empty ImageData从 Canvas 上下文中,然后将其所有 .data 的值设置为新值。

//////////////////////////////
// Distortion Filter //
// Originally by JoelBesada //
//////////////////////////////
class FilterDistortion {
constructor() {
this.name = 'Distortion';
this.defaultValues = {
size: 4,
density: 0.5,
mix: 0.5,
};
this.valueRanges = {
size: { min: 1, max: 10 },
density: { min: 0.0, max: 1.0 },
mix: { min: 0.0, max: 1.0 },
};
}

filter(input, values = this.defaultValues) {
const { width, height } = input;

const inputData = input.data;
const outputData = inputData.slice();

let size = (values.size === undefined)
? this.defaultValues.size
: parseInt(values.size, 10);
if (size < 1) size = 1;

const density = (values.density === undefined)
? this.defaultValues.density
: Number(values.density);

const mix = (values.mix === undefined)
? this.defaultValues.mix
: Number(values.mix);

const radius = size + 1;
const numShapes = parseInt(((((2 * density) / 30) * width) * height) / 2, 10);

for (let i = 0; i < numShapes; i++) {
const sx = (Math.random() * (2 ** 32) & 0x7fffffff) % width;
const sy = (Math.random() * (2 ** 32) & 0x7fffffff) % height;

const rgb2 = [
inputData[(((sy * width) + sx) * 4) + 0],
inputData[(((sy * width) + sx) * 4) + 1],
inputData[(((sy * width) + sx) * 4) + 2],
inputData[(((sy * width) + sx) * 4) + 3],
];

for (let x = sx - radius; x < sx + radius + 1; x++) {
for (let y = sy - radius; y < sy + radius + 1; y++) {
if (x >= 0 && x < width && y >= 0 && y < height) {
const rgb1 = [
outputData[(((y * width) + x) * 4) + 0],
outputData[(((y * width) + x) * 4) + 1],
outputData[(((y * width) + x) * 4) + 2],
outputData[(((y * width) + x) * 4) + 3],
];
const mixedRGB = this.mixColors(mix, rgb1, rgb2);

for (let k = 0; k < 3; k++) {
outputData[(((y * width) + x) * 4) + k] = mixedRGB[k];
}
}
}
}
}

return outputData;
}

linearInterpolate(t, a, b) {
return a + (t * (b - a));
}

mixColors(t, rgb1, rgb2) {
const r = this.linearInterpolate(t, rgb1[0], rgb2[0]);
const g = this.linearInterpolate(t, rgb1[1], rgb2[1]);
const b = this.linearInterpolate(t, rgb1[2], rgb2[2]);
const a = this.linearInterpolate(t, rgb1[3], rgb2[3]);

return [r, g, b, a];
}
}

/////////////////
// Driver Code //
/////////////////
var img = new Image(); img.crossOrigin=1; img.onload = draw; img.src = "//i.imgur.com/Kzz84cr.png";
function draw() {
c.width = this.width; c.height = this.height;

var ctx = c.getContext("2d");
// main loop
ctx.drawImage(this, 0, 0); // draw video frame
var data = ctx.getImageData(0, 0, c.width, c.height);
var distortedData = new FilterDistortion().filter(data);
var distortedImg;
try{
distortedImg = new window.ImageData(distortedData, c.width, c.height);
}
catch(e) {
distortedImg = ctx.createImageData(c.width, c.height);
distortedImg.data.set(distortedData);
}
ctx.putImageData(distortedImg, 0, 0);
ctx.globalCompositeOperation = "source-over"; // "reset"
// rinse, repeat
}
<canvas id=c></canvas>

关于javascript - 为 HTML Canvas 创建自己的过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49311237/

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