One approach is to create a buffer image that lists your block values (one per pixel), then scale those results.
- Create the buffer with
PImage.resize()
. - Scale the output with
image(src, x, y, w, h)
– whilenoSmooth()
is turned on.
/**
* ScaledImageBlockSize
* 2019-01-12 Jeremy Douglass - Processing 3.4
* https://discourse.processing.org/t/pixelating-sketch/7791
*/
PImage img;
PImage valuesImg;
int BLOCKWIDTH = 10;
int BLOCKHEIGHT = 3;
void setup() {
size(264, 480);
noSmooth();
img = loadImage("https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Processing_3_logo.png/240px-Processing_3_logo.png");
// trim the img to an exact multiple of our block size, cropping the right and bottom edge
int cropWidth = img.width - img.width%BLOCKWIDTH;
int cropHeight = img.height - img.height%BLOCKHEIGHT;
img = img.get(0, 0, cropWidth, cropHeight);
// scale img down to one pixel per block, using the resize algorithm. No need to reinvent the wheel
int scaleWidth = cropWidth / BLOCKWIDTH;
int scaleHeight = cropHeight / BLOCKHEIGHT;
valuesImg = img.copy();
valuesImg.resize(scaleWidth, scaleHeight);
}
void draw() {
background(255);
// original image
image(img, 0, 0);
// scaled image -- one pixel per block
image(valuesImg, img.width, 0);
// upscaled output, with one 10x3 pixel region per block.
// this depends on noSmooth() being set, or upscale will blur.
// the 5-arg image command is also really inefficient to do every frame!
// instead, consider drawing only once into a buffer.
image(valuesImg, 0, img.height, img.width, img.height);
}
In general, this makes the process very clear in code, but isn’t the most efficient approach. If you want real performance, my guess would be that you should some version of the pixelate shader method described in the PShader tutorial – although this requires shaders, which can be advanced: