繁体   English   中英

为HTML Canvas制作自己的过滤器

[英]Make your own filter for HTML Canvas

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

无法在'CanvasRenderingContext2D'上执行'putImageData':参数1不是'ImageData'类型

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

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

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

 ////////////////////////////// // 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。

因此,您将不得不从该TypedArray创建一个新的ImageData (当ImageData构造函数可用时),或者从您的画布上下文创建一个空的ImageData ,然后将其所有.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> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM