Search code examples
pythonimagergb

How to invert the green channel of an image in Python?


How do I invert one channel of an RGB image? In this case my image is a normal map for a 3D engine, saved in an image format like JPEG or TIFF, and I want to invert the green channel — that is, completely reverse the highs and lows in the green band.


Solution

  • You can accomplish this by installing and using Pillow, which can work with most image formats (JPEG, PNG, TIFF, etc.).

    from PIL import Image
    from PIL.ImageChops import invert
    
    image = Image.open('test.tif')
    red, green, blue = image.split()
    image_with_inverted_green = Image.merge('RGB', (red, invert(green), blue))
    image_with_inverted_green.save('test_inverted_green.tif')
    

    After loading the image from your file, split into its channels with Image.split, invert the green channel/image with ImageChops.invert, and then join it together with the original red and blue bands into a new image with Image.merge.

    If using a format that's encoded in something other than RGB (such as PNG, which has an additional transparency channel), the image-opening line can be amended to:

    image = Image.open('test.png').convert('RGB')
    

    Testing with this image:

    test.tif

    Produces this:

    test_with_inverted_green.tif

    (ImageChops, by the way, looks like a very odd term, but it's short for "image channel operations".)