forked from davidflanagan/jstdg7
-
Notifications
You must be signed in to change notification settings - Fork 0
/
smear.js
38 lines (32 loc) · 1.84 KB
/
smear.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Smear the pixels of the rectangle to the right, producing a
// sort of motion blur as if objects are moving from right to left.
// n must be 2 or larger. Larger values produce bigger smears.
// The rectangle is specified in the default coordinate system.
function smear(c, n, x, y, w, h) {
// Get the ImageData object that represents the rectangle of pixels to smear
let pixels = c.getImageData(x, y, w, h);
// This smear is done in-place and requires only the source ImageData.
// Some image processing algorithms require an additional ImageData to
// store transformed pixel values. If we needed an output buffer, we could
// create a new ImageData with the same dimensions like this:
// let output_pixels = c.createImageData(pixels);
// Get the dimensions of the grid of pixels in the ImageData object
let width = pixels.width, height = pixels.height;
// This is the byte array that holds the raw pixel data, left-to-right and
// top-to-bottom. Each pixel occupies 4 consecutive bytes in R,G,B,A order.
let data = pixels.data;
// Each pixel after the first in each row is smeared by replacing it with
// 1/nth of its own value plus m/nths of the previous pixel's value
let m = n-1;
for(let row = 0; row < height; row++) { // For each row
let i = row*width*4 + 4; // The offset of the second pixel of the row
for(let col = 1; col < width; col++, i += 4) { // For each column
data[i] = (data[i] + data[i-4]*m)/n; // Red pixel component
data[i+1] = (data[i+1] + data[i-3]*m)/n; // Green
data[i+2] = (data[i+2] + data[i-2]*m)/n; // Blue
data[i+3] = (data[i+3] + data[i-1]*m)/n; // Alpha component
}
}
// Now copy the smeared image data back to the same position on the canvas
c.putImageData(pixels, x, y);
}