Javascript 在画布上应用平滑过滤器

Javascript 在画布上应用平滑过滤器,javascript,html,canvas,Javascript,Html,Canvas,我有以下画布,其中有许多小(15x15)块: 我想做的是添加一个过滤器来去除方框之间的边界,使图片更加一致,这样矩形就不会太明显,也不会太平滑。我可以使用什么过滤器或算法来实现这一目标 请注意,我不能改变我创建画布的方式,我必须绘制一组矩形,以便生成最终形状。如果问题不够清楚,请道歉。使用getImageData立即获取任意像素周围的数据,并将它们融合到临时画布上。通过主画布上的drawImage结束 var c=document.body.appendChild(document.crea

我有以下画布,其中有许多小(15x15)块:

我想做的是添加一个过滤器来去除方框之间的边界,使图片更加一致,这样矩形就不会太明显,也不会太平滑。我可以使用什么过滤器或算法来实现这一目标


请注意,我不能改变我创建画布的方式,我必须绘制一组矩形,以便生成最终形状。如果问题不够清楚,请道歉。

使用
getImageData
立即获取任意像素周围的数据,并将它们融合到临时画布上。通过主画布上的
drawImage
结束

var c=document.body.appendChild(document.createElement(“canvas”);
变量大小=c.宽度=c.高度=50;
var tileSize=5;
var=0;
var ctx=c.getContext(“2d”);
c、 style.width=c.style.height=“400px”;
对于(变量x=0;x0.5?#FF0000):(Math.random()>0.5?#00FF00:“#0000FF”);
fillRect(x+填充,y+填充,tileSize-padding,tileSize-padding);
}
}
函数模糊(画布){
var ctx=canvas.getContext(“2d”);
var tempCanvas=canvas.cloneNode();
var tempCTX=tempCanvas.getContext(“2d”);
var除以=9;
对于(变量x=0;x设置超时(步骤1000)
使用
getImageData
立即获取任意一个像素周围的数据,并将它们融合到临时画布上。通过主画布上的
drawImage
结束

var c=document.body.appendChild(document.createElement(“canvas”);
变量大小=c.宽度=c.高度=50;
var tileSize=5;
var=0;
var ctx=c.getContext(“2d”);
c、 style.width=c.style.height=“400px”;
对于(变量x=0;x0.5?#FF0000):(Math.random()>0.5?#00FF00:“#0000FF”);
fillRect(x+填充,y+填充,tileSize-padding,tileSize-padding);
}
}
函数模糊(画布){
var ctx=canvas.getContext(“2d”);
var tempCanvas=canvas.cloneNode();
var tempCTX=tempCanvas.getContext(“2d”);
var除以=9;
对于(变量x=0;x设置超时(步骤1000)这样做是为了好玩,而不是真正的帮助。但你可以得到基本的想法,请继续阅读:)

生成位图,获取纯色数组(例如imageData),获取图像的宽度并将其乘以4([r,g,b,a]是一个像素)()

如果你愿意-你可以修改它做一些“放数据”循环和多重方向15得到这种“块状”风格

然后-做你想做的。举例来说,我会:

const channelResolution = 4; // if you don't have somehow alpha channel - make it 3.
const lineDistance = imageWidth * channelResolution;
const imageData = [ /* your ImageData from canvas */];

const [r, g, b, a] = [0, 1, 2, 3]; // directions inside channels
const [left, right, up, down] = [
    -channelResolution,
    channelResolution,
    -lineDistance,
    lineDistance]; // directions inside pixels

// return array of channel values in given directions
const scan = (data, scanChannel, scanPixel, scanDirections) => {
    const scanResult = [];

    scanResult.push(data[scanPixel + scanChannel]);
    return scanResult.concat(scanDirections.map(direction => {
        return data[scanPixel + scanChannel + direction];
    }));
};

// mixer filter
const mixChannel = (array) => {
    let sum = 0;
    array.map(channel => sum+=channel);
    return sum / (array.length + 1);
};

// blur edge filter/shader
const blurEdges = () => {
  const resultData = clone(imageData); // (you can do json transformation)
  for(let pointer = 0; pointer < imageData * channelResolution - channelResolution; pointer += channelResolution) {
    const [red, green, blue, alpha] = [
        mixChannel(scan(imageData, r, pointer, [up, left, down, right])),
        mixChannel(scan(imageData, g, pointer, [up, left, down, right])),
        mixChannel(scan(imageData, b, pointer, [up, left, down, right])),
        mixChannel(scan(imageData, a, pointer, [up, left, down, right])),
    ];

    resultData[pointer + r] = red;
    resultData[pointer + g] = green;
    resultData[pointer + b] = blue;
    resultData[pointer + a] = alpha;
  }
  return resultData; // or putImageData
}
const channelResolution=4;//如果你没有alpha通道,就把它设为3。
const lineDistance=图像宽度*通道分辨率;
const imageData=[/*画布上的imageData*/];
常数[r,g,b,a]=[0,1,2,3];//通道内的方向
常量[左、右、上、下]=[
-决议,
决议,
-线路距离,
线宽];//像素内的方向
//返回给定方向上的通道值数组
常量扫描=(数据、扫描通道、扫描像素、扫描方向)=>{
常量扫描结果=[];
push(数据[scanPixel+scanChannel]);
返回scanResult.concat(scanDirections.map(方向=>{
返回数据[扫描像素+扫描通道+方向];
}));
};
//混频器滤波器
const mixChannel=(数组)=>{
设和=0;
map(channel=>sum+=channel);
返回和/(数组长度+1);
};
//模糊边缘过滤器/着色器
常数模糊边=()=>{
const resultData=clone(imageData);//(可以进行json转换)
for(让指针=0;指针<图像数据*通道分辨率-通道分辨率;指针+=通道分辨率){
常数[红、绿、蓝、阿尔法]=[
混合通道(扫描(图像数据、r、指针、[上、左、下、右]),
混合通道(扫描(图像数据、g、指针[上、左、下、右]),
混合通道(扫描(成像