Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swap R and B color channel values in a directory of images? Python

I've got a big directory of screenshots. Silly me I didn't check that they were coming out fine and found out the hard way VLC has a bug with FRAPS True RGB. Luckily it seems fixable, it looks like the only problem is that the R and B channels were swapped.

Using python's PIL I'd like to grab the red and blue values for each pixel for each image and then reinsert them swapped.

I know how to walk through a directory so the main piece I'm missing is the best way to swap the values. I think I could do it pixel for pixel but maybe there's a more pythonic way, perhaps batching it all in one command?

Any example code or links would be highly appreciated!

like image 494
veta Avatar asked Jul 02 '15 22:07

veta


3 Answers

Building on @veta's answer, the process may be greatly accelerated by working on color channels instead of individual pixels:

In the loop for each file, channels may be swapped like this:

r, g, b = im_rgb.split()
im_rgb = Image.merge('RGB', (b, g, r))

Just use these two lines instead of the nested loops in veta's answer. This should run considerably faster.

This solution first uses Image.split() to create three separate images, one for each R, G, B, channel. Then Image.merge() is used to create a new RGB image with swapped R and B channels.

like image 127
Ber Avatar answered Sep 30 '22 13:09

Ber


You can let ImageMagick do that for you. Let's make a red-black gradient image like this:

convert -size 256x100 gradient:red-black in.png

enter image description here

Now we can load it up, separate the R, G and B channels, swap the Red with the Blue and recombine them into the output image:

convert in.png -separate -swap 0,2 -combine out.png

enter image description here

ImageMagick is installed on most Linux distros and available for OSX (ideally via homebrew) and also for Windows from here.

If you want to do a whole directory of PNG files, for example, you would do

find . -iname "*.png" -exec convert "{}" -separate -swap 0,2 -combine {} \;

if you are on Linux or OS X.

If you are on Windows, you would need to do something like this with the mad Windows syntax:

FOR %%F in (*.PNG) DO convert "%%F" -separate -swap 0,2 -combine "%%F
like image 40
Mark Setchell Avatar answered Sep 30 '22 13:09

Mark Setchell


import os
from PIL import Image


dirPath = r"D:\Fraps\Movies\Screens"
dirList = os.listdir(dirPath)
outPath = r"D:\Fraps\Movies\Screens\Output"

for (dirname, dirs, files) in os.walk(dirPath):
   for filename in files:
       if filename.endswith('.png'):
            print("Opening:"+filename)
            thefile = os.path.join(dirname,filename)
            im = Image.open(thefile)
            #im.load()

            width, height = im.size

            im_rgb = im.convert('RGB')

            for x in range(0, width):
                for y in range(0,height):
                    r, g, b = im_rgb.getpixel((x, y))
                    im_rgb.putpixel((x, y), (b, g, r))

            print("Saving:"+filename)
            #outfile, ext = os.path.splitext(infile)
            outfile = os.path.join(outPath,filename)
            im_rgb.save(outfile, "PNG")


print("Ding!")
like image 43
veta Avatar answered Sep 30 '22 13:09

veta