Skip to content

Instantly share code, notes, and snippets.

@gncgnc
Last active June 7, 2023 01:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save gncgnc/fc645b8db00ec43d43fecef37d58df73 to your computer and use it in GitHub Desktop.
Save gncgnc/fc645b8db00ec43d43fecef37d58df73 to your computer and use it in GitHub Desktop.
Extends p5.Image to handle nearest neighbor resizing for scaling small images (e.g. pixel art) without blurring. You can also make regular images into pixelated images by shrinking then growing them with this method (a la MS Paint.)
/**
* 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 parameter.
* 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(width, height) {
if (width === 0 && height === 0) {
width = this.canvas.width;
height = this.canvas.height;
} else if (width === 0) {
width = this.canvas.width * height / this.canvas.height;
} else if (height === 0) {
height = this.canvas.height * width / this.canvas.width;
}
width = Math.floor(width);
height = Math.floor(height);
var temp = createImage(width,height),
xScale = width / this.width ,
yScale = height / this.height
this.loadPixels()
temp.loadPixels()
for(var x=0; x<temp.width; x++) {
for(var y=0; y<temp.height; y++) {
var sourceInd = 4*(Math.floor(y/yScale)*this.width + Math.floor(x/xScale))
var targetInd = 4*(y*temp.width + x)
var sourceP = this.pixels.slice(sourceInd,sourceInd+4)//this.get(x/wScale, y/hScale)
temp.pixels[targetInd] = sourceP[0]
temp.pixels[targetInd+1] = sourceP[1]
temp.pixels[targetInd+2] = sourceP[2]
temp.pixels[targetInd+3] = sourceP[3]
}
}
temp.updatePixels()
this.updatePixels()
this.canvas.width = this.width = width;
this.canvas.height = this.height = height;
this.drawingContext.drawImage(temp.canvas,
0, 0, width, height,
0, 0, width, height
)
};
@GoToLoop
Copy link

GoToLoop commented Mar 8, 2017

Hello! Have you asked for performance suggestions?
I've just refactored your whole resizeNN() gist in hopes it gets faster.
No idea whether it's achieved that somehow. But you can check that out at my forked gist link below:
https://Gist.GitHub.com/GoToLoop/2e12acf577506fd53267e1d186624d7c

@gncgnc
Copy link
Author

gncgnc commented Mar 19, 2017

I'll have to test and see but it seems like there should at least be a marginal improvement. Thanks for taking the time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment