Replace colors in an image without having to iterate through all pixels


#1

Let’s say that I have an image like this (in reality, I have a lot of them next to eachother, but let’s keep it simple)
vt
example picture and I’d like to replace background color (that’s the one that’s not roads) with green color.

To do that I’d have to iterate through all of the pixels in the map and replace ones that match the color I want to remove.

But as you might think, my image is not a simple as 256x256 picture, but it’s slightly bigger, it’s 1440p, and the performance drop is significant.

How would I replace all of the unwanted pixels without iterating through all of the pixels.

I’m working with Processing 3 - Java(Android) and I’m currently using this piece of code:

for (x = 0; x < img.width; x++){
    for (int y = 0; y < img.height; y++) {
         //Color to transparent
         int index = x + img.width * y;
         if (img.pixels[index] == -1382175 || img.pixels[index] == 14605278 || img.pixels[index] == 16250871) {
            img.pixels[index] = color(0, 0, 0, 0);
         } else {
            img.pixels[index] = color(map(bright, 0, 255, 64, 192));
         }
    }
}

#2

Solved it with this one:

private PImage swapPixelColor(PImage img, int old, int now) {
        old &= ~0x00000000;
        now &= ~0x00000000;

        img.loadPixels();
        int p[] = img.pixels, i = p.length;

        while (i-- != 0) if ((p[i]) == old) p[i] = now;

        img.updatePixels();
        return img;
    }

It works like a charm and it takes almost no time:

Swapped colors in 140ms // That's replacing it three times(different colors ofc)

#3

Thanks for sharing your solution!

Out of curiosity, are you swapping these colors once, to a cached image, or are you swapping the pixel values every single frame? If performance is an issue, not recalculating the same thing every single frame is another potential strategy.


#4

I’m only calculating it in setup, so it calculates it only once… But the loading times were around few minutes for 1280x720 image, so that’s slow. It’s working well now :slight_smile:

And no problem for the solution, if it helped me, why not post it?