2
votes

I have 1000+ images in a directory labelled:
x_1.bmp
x_2.bmp
x_3.bmp
y_1.bmp
y_3.bmp
...etc

Ideally, I'd like to overlay all files with a similar name and export as x_P.png, y_P.png, etc. as below. All images are the same size and none of the colour pixels overlap.

x_1 example + x_2 example + x_3 example = enter image description here

I've tried to batch overlay images using a merge-divide script function in GIMP/BIMP without success. Would PIL.Image.Image.paste() be able to do this, or something similar? I'm using Windows and Python 3.7.3

Thanks

2
So, you want to convert all files from .bmp to .png? What do you mean by "overly all files with a similar name"?Ayush Garg
Yes, I'll need to save the final image as a png but this can be done separately if necessary. All files starting with x should be merged into one image, all files starting with y should be merged into a separate image. All images are the same size.user13024726
What do you mean by "merge"? Are the images going to be layered on top of each other, placed next to each other, etc.Ayush Garg
Layered on top of each otheruser13024726
Is x_1.bmp the red channel and x_2.bmp the green channel? Please show your images and the expected result, else we are all guessing and wasting our time. Thank you.Mark Setchell

2 Answers

0
votes

Working off the example from the other answer I managed to sort this and maintain the RGB values.

import os
from PIL import Image
import PIL
import itertools as it


path = path/to/files
alpha = 1
list_of_imgs = sorted(os.listdir('path'))
for k,g in it.groupby(list_of_imgs, key=lambda x: x.split('_')[0]): 
    img = Image.open('path/{}'.format(next(g)),'r').convert('RGBA') 
    x,y = img.size 
    g_list = list(g) 
    for i,item in enumerate(g_list): 
        next_img = Image.open('path/{}'.format(item)).convert('RGBA')
        if i == 0: 
            new_img = Image.alpha_composite(next_img,img) 
        else: 
            new_img = Image.alpha_composite(next_img,new_img) 
        next_img.paste(new_img, (0,0,x,y), mask=new_img) 
        new_img.save(f'path/{k}_P.png',format='png') 


Image.open(path + r"/output_P.png").getcolors()

Result

Result

0
votes

I was able to do this for a small number of images. I'm not sure what it would accomplish with a lot of images, though, since everything would jumble together. Anyway, let me know if it helps. I am using pillow version 7.0.0 here.

import os
import itertools as it
from PIL import Image

alpha = 0.5
list_of_imgs = sorted(os.listdir('images'))
for k,g in it.groupby(l,key=lambda x: x.split('_')[0]): 
    img = Image.open('images/{}'.format(next(g)),'r').convert('RGBA') 
    x,y = img.size 
    g_list = list(g) 
    for i,item in enumerate(g_list): 
        next_img = Image.open('images/{}'.format(item)).convert('RGBA')
        if i == 0: 
            new_img = Image.blend(next_img,img,alpha) 
        else: 
            new_img = Image.blend(next_img,new_img,alpha) 
        next_img.paste(new_img, (0,0,x,y), mask=new_img) 
        new_img.save(f'images/{k}.png',format='png') 

Result for three images (dog/puppy, mountain peak, lighthouse): enter image description here