-
Notifications
You must be signed in to change notification settings - Fork 0
/
resizeNN.js
55 lines (42 loc) · 2.08 KB
/
resizeNN.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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
* Resize the image to a new width and height using nearest neigbor algorithm.
* To make the image scale proportionally, use 0 as the value for the wide or high parameters.
* For instance, to make the width of an image 150 pixels,
* and change the height using the same proportion, use resize(150, 0).
* Otherwise same usage as the regular resize().
*
* Note: Disproportionate resizing squashes the "pixels" from squares to rectangles.
* This works about 10 times slower than the regular resize.
* Any suggestions for performance increase are welcome.
*/
p5.Image.prototype.resizeNN = function (w, h) {
"use strict";
// Locally cache current image's canvas' dimension properties:
const {width, height} = this.canvas;
// Sanitize dimension parameters:
w = ~~Math.abs(w), h = ~~Math.abs(h);
// Quit prematurely if both dimensions are equal or parameters are both 0:
if (w === width && h === height || !(w | h)) return this;
// Scale dimension parameters:
w || (w = h*width / height | 0); // when only parameter w is 0
h || (h = w*height / width | 0); // when only parameter h is 0
const img = new p5.Image(w, h), // creates temporary image
sx = w / width, sy = h / height; // scaled coords. for current image
this.loadPixels(), img.loadPixels(); // initializes both 8-bit RGBa pixels[]
// Create 32-bit viewers for current & temporary 8-bit RGBa pixels[]:
const pixInt = new Int32Array(this.pixels.buffer),
imgInt = new Int32Array(img.pixels.buffer);
// Transfer current to temporary pixels[] by 4 bytes (32-bit) at once:
for (let y = 0; y < h; ) {
const curRow = width * ~~(y/sy), tgtRow = w * y++;
for (let x = 0; x < w; ) {
const curIdx = curRow + ~~(x/sx), tgtIdx = tgtRow + x++;
imgInt[tgtIdx] = pixInt[curIdx];
}
}
img.updatePixels(); // updates temporary 8-bit RGBa pixels[] w/ its current state
// Resize current image to temporary image's dimensions:
this.canvas.width = this.width = w, this.canvas.height = this.height = h;
this.drawingContext.drawImage(img.canvas, 0, 0, w, h, 0, 0, w, h);
return this;
};