This is a very interesting special effect, simulating the dot-like grainy effect that appears when a camera captures a TV screen. The size of the particles is realized through the transformation matrix and can be adjusted arbitrarily. Friends who are interested in research can try more effects. The code has not been optimized and is just a rough demo. You can improve it yourself.
1. Get image data
img.src = 'http://bloglaotou.duapp.com/wp-content/themes/frontopen2/tools/filter/image2.jpg';
canvas.width = img.width ;
canvas.height = img.height;
var context = canvas.getContext(“2d”);
context.drawImage(img, 0, 0);
var canvasData = context.getImageData (0, 0, canvas.width, canvas.height);
2. Set the filter matrix
var m_VideoType=0;
var pattern=new Array();
switch (m_VideoType)
{
case0://VIDEO_TYPE.VIDEO_STAGGERED:
{
pattern = [
0, 1,
0, 2,
1, 2,
1, 0 ,
2, 0,
2, 1,
];
break;
}
case1://VIDEO_TYPE.VIDEO_TRIPED:
{
pattern = [
0,
1,
2,
];
break;
}
case2://VIDEO_TYPE.VIDEO_3X3:
{
pattern =
[
0, 1, 2,
2, 0, 1,
1, 2, 0,
];
break;
}
default:
{
pattern =
[
0, 1, 2, 0, 0,
1, 1, 1, 2, 0,
0, 1, 2, 2, 2 ,
0, 0, 1, 2, 0,
0, 1, 1, 1, 2,
2, 0, 1, 2, 2,
0, 0, 0, 1 , 2,
2, 0, 1, 1, 1,
2, 2, 0, 1, 2,
2, 0, 0, 0, 1,
1, 2, 0 , 1, 1,
2, 2, 2, 0, 1,
1, 2, 0, 0, 0,
1, 1, 2, 0, 1,
1, 2 , 2, 2, 0,
];
break;
}
}
var pattern_width = [ 2, 1, 3, 5 ];
var pattern_height = [6, 3, 3, 15 ];
3. Get filtered data
for ( var x = 0; x < canvasData.width; x ) {
for ( var y = 0; y < canvasData. height; y ) {
// Index of the pixel in the array
var idx = (x y * canvasData.width) * 4;
var r = canvasData.data[idx 0];
var g = canvasData.data[idx 1];
var b = canvasData.data[idx 2];
var nWidth = pattern_width[m_VideoType];
var nHeight = pattern_height[m_VideoType];
var index = nWidth * (y % nHeight) (x % nWidth);
index = pattern[index];
if (index == 0)
var r = fclamp0255(2 * r);
if (index == 1)
var g = fclamp0255(2 * g);
if (index == 2)
var b = fclamp0255(2 * b);
// assign gray scale value
canvasData.data[idx 0] = r; // Red channel
canvasData.data[idx 1] = g; // Green channel
canvasData.data[idx 2] = b ; // Blue channel
canvasData.data[idx 3] = 255; // Alpha channel
// Add black border
if(x < 8 || y < 8 || x > (canvasData.width - 8) || y > (canvasData.height - 8))
{
canvasData.data[idx 0] = 0;
canvasData.data[idx 1] = 0;
canvasData.data[idx 2] = 0;
}
}
}
4. Write filtered data
context.putImageData(canvasData, 0, 0 );
5. Reference materials Dai Zhenjun ImageFilter open source project