Color Invert

At some point, you have probably seen an inverted image before, like on the right. This is where any individual pixel in an image takes on the “opposite” value. It’s a pretty simple effect, but it makes things look so strange, because it also makes dark parts of an image bright, and bright parts dark. So instead of an inverting filter, we are going to make a color inverting filter, where it will keep the total brightness of a pixel the same, but invert only the color, so that light red pixel would become a light cyan pixel, or a dark green would become a dark magenta.

Like with our black and white filter, we once again want to think about the overall brightness of an individual pixel, and its once again useful to think of a specific pixel to think about how we would do that. Consider a pixel with the rgb value of 100, 0, 0. What is its overall brightness? How would we invert the colors without changing that overall brightness? What would its final, inverted color values be?

In the case of this pixel, we would want to take the red value, and split it amongst the green and blue values for an end result of 0, 50, 50. This was straightforward enough, but what about a pixel that has more than one value with color in it? We’re going to want to set up new variables for each color. Red will become the sum of half the green and blue values, blue will be the sum of red and green, and green will be the sum of red and blue.

Like last time, start with a copy of the cyanify function, changing the name to colorInvert, and removing the line “red = 0”.

def (image):
    width, height = image.size
    for x in range(width):
        for y in range(height):
            red, green, blue = image.getpixel((x,y))

            image.putpixel((x, y), (red, green, blue))
    return image

Now we can insert the code to calculate our new pixel color, and set the pixel to the newRed, newGreen, and newBlue values we found.

def (image):
    width, height = image.size
    for x in range(width):
        for y in range(height):
            red, green, blue = image.getpixel((x,y))
            
newRed = int(blue/2 + green/2)
            newGreen = int(red/2 + green/2)
            newBlue = int(green/2 + blue/2)
            image.putpixel((x, y), (newRed, newGreen, newBlue))
    return image

Running this code should produce an image like the one to the right, where the colors have been converted to their opposites, but the brightness still looks about right.

This will be the last filter we make in this lesson, however feel free to explore python and see what other filters you can come up with. Part of the fun of coding is playing around and seeing what sticks!