Pixelate and Posterize in Processing

After an afternoon of working on a Processing project with Alex Myers, I created a Processing sketch that pixelates and posterizes an image.  Next step (and definitely the hardest) will be to find the weighted center of the pixel areas (not each pixel block but areas of the same color).  The above image is Van Gogh’s “Starry Night”.

[ view the source code here | download the zipped version with source image here ]

8 Replies to “Pixelate and Posterize in Processing”

  1. Jeff,

    Awesome project! It was just what I was looking for. Pixelating and Posterizing in one. I do have a question though, if you wouldn’t mind answering. It seems as though Processing won’t accept variables when setting the size in setup(). I end up hardcoding the size to match the size of the image I’m using. When the sketch runs and gets to the part in your pixelateImage() function, specifically, the part where it sets the ratio by dividing the height and width, I always seem to get a rounded number. I’m using an image that is sized 640W x 480H, and yet, when I use the debugger to view that value of the ratio variable, it comes out to 1.0. It should be 1.3. I’ve even tried other values for width and height. I always seems to get a rounded number. Any idea why? I don’t see anything in your code that rounds up. Or maybe I am missing it. Thanks a lot in advance. Great sketch too!

  2. Thanks Ryan! The newest version of Processing doesn’t easily let you put variables in size(), which drives me crazy. Hard-coding is one option, as would be writing to a separate PGraphics instance, then saving it out to file.

    The ratio thing is probably a legacy code issue too – you have to explicitly say the result of width/height is a float like this: ratio = (float) height/width;.

  3. Thanks for the reply! What you said makes sense.

    I think what was throwing me off was that I was expecting a number like 1.3 from the result of your if statement. But I wasn’t considering the fact that both height and width are, by default, Int’s. That would explain why I was getting a round number with nothing after the decimal. Casting the result of height/width using (float) gives me the number I was looking for. You were correct about that. However, it confirms what I was suspecting about getting a float as a result. The ratio variable, if its anything BUT a round number, will result in non-square pixels being drawn. (i.e. a few lines ahead in your code where you draw a rectangle by saying “rect(x, y, pxSize, pxH);”). The rectangle that gets drawn will be non-square if the ratio variable equals anything other than a round number. You get oblong squares being drawn instead of perfectly square ones. I’ve confirmed this by comparing the two resulting images. I would be happy to show you, but I’m sure you know what I mean.

    It’s not an issue by any means. I’m just very determined to fully understand how your sketch works. I’m relatively new to programming so I’m in a phase of learning and understanding. It’s a great sketch. Its gets the exact result I was looking for and I’m glad I came across it. Now if I could only figure out how to remap the colors from grayscale to “greenscale”……(yes I did just make that word up)

  4. The pixels are non-square because width and height are different! You could use min(pxWidth, pxHeight) to get one value to make square pixels. To go to “greenscale” you could just map your grayscale value into green!

    int bright = int(brightness(pixels[i])/rangeSize) * rangeSize;
    pixels[i] = color(0, bright, 0); // set to green value of RGB

  5. can we have a python version of this? The double for loops look really scary to implement there.

  6. @Ankur – it should be pretty easy to port to Python! No need to be scared of double loops :)

    It would be something like this:

  7. @Chase – for the posterize code? It would be possible but way more complicated. I think you’d have to keep track of the colors you wanted to use in an array, adding them as you hit the varying brightness levels. If this sounds like too much bother, I’d suggest using the built-in POSTERIZE filter in Processing.

Leave a Reply

Your email address will not be published. Required fields are marked *