我目前正在研究javascript中的水平模糊算法,不过我怀疑语言是否重要。
我从画布中获取数据,该画布基本上是一个巨大的数组,其中每四个(RGBA)值代表一个像素。值可以包含0到255之间的int。
当我模糊图像时,两种不同颜色之间的区域会变成奇怪的颜色!我在黑色背景上画了一个红色矩形。使用下面的算法,我得到以下结果(4px大小):
虽然当使用1或2像素大小时,一切似乎都能正常工作。
请注意,这有点混乱。我打算把这个全部用于OOP!
// s: size
// w: width
// h: height
function blur( s, w, h ) {
var src = ctx.getImageData( 0, 0, w, h ); // get imagedata from source
var dst = ctx.createImageData( w, h ); // create imagedata for dest
var x, y, xo, index, rgb; // predefine vars
// loop through y axis
for( y = 0; y < h; y++ ) {
// loop through x axis
for( x = 0; x < w; x++ ) {
rgb = 0; // set total to 0
// loop through area around current pixel
for( xo = 0 - s; xo <= s; xo++ ) {
// get specific index
index = getIndex( x + xo, y, w );
// add nothing if the value doesn't exist (borders)
// if( isNaN( src.data[index] ) ) continue;
if( typeof src.data[index] === 'undefined' ) continue;
// add the values to total
rgb += ( src.data[index] << 16 ) + ( src.data[index + 1] << 8 ) + src.data[index + 2];
}
// get the average of all pixels in that area
rgb = rgb / ( s * 2 + 1);
// get index of current pixel
index = getIndex( x, y, w );
// set pixel in dest
dst.data[index] = ( rgb & 0xff0000 ) >> 16; // red
dst.data[index + 1] = ( rgb & 0x00ff00 ) >> 8; // green
dst.data[index + 2] = ( rgb & 0x0000ff ); // blue
dst.data[index + 3] = 255; // alpha
}
}
// add the new image data
ctx.putImageData( dst, 0, 0 );
}
function getIndex( x, y, w ) {
// calculate the appropriate index, since every pixel has 4 array values
return ( y * ( w * 4 ) + ( x * 4 ) );
}
所以我的算法出了什么问题?我有点迷失了。请注意,我不是在寻找画布模糊的现有对象/库/文件。我喜欢重新发明一切来教育自己。
编辑:我还想补充一点,我得到的值确实是代表画布上显示的颜色的值。这意味着我的算法肯定是一个错误的计算。
答案 0 :(得分:2)
您应该分别对频道进行平均。分割打包的三通道值不太可能将每个通道保持在其字节内。
答案 1 :(得分:2)
0x030000
(深红色)和0x000000
(黑色)之间的平均值变为0x018000
,这会得到很多绿色(0x80)
您应该分别对通道进行平均。