Add white background and resize images in a folder

Question:

I want to add a white background to my transparant images (png) and resize them. The images are located in a folder. I need to do bulk work, not 1 image at the time.

I removed the background from the images first with rembg (works good) and now I want to change the images.

My code

import rembg
import glob
from pathlib import Path
from rembg import remove, new_session

session = new_session()

for file in Path(r'C:testimages').glob('*.jpg'):
    input_path = str(file)
    output_path = str(file.parent / (file.stem + ".out.png"))

    with open(input_path, 'rb') as i:
        with open(output_path, 'wb') as o:
            input = i.read()
            output = remove(input, session=session)
            o.write(output)

I do not know how to add the white backgroud and resize with python because I’m fairly new to this. Thank you in advance!

Asked By: Deidraak

||

Answers:

I think you want a helper function to do the work, something like:

from PIL import Image
import rembg

def process(session, image, *, size=None, bgcolor='white'):
    "session is a rembg Session, and image is a PIL Image"
    if size is not None:
        image = image.resize(size)
    else:
        size = image.size
    result = Image.new("RGB", size, bgcolor)
    out = rembg.remove(image, session=session)
    result.paste(out, mask=out)
    return result

The idea being that you pass a rembg Session and a Pillow Image in and it will remove the background and flatten that image, resizing along the way.

As a working example, you could do something like:

from io import BytesIO
import requests

session = rembg.new_session("u2netp")

res = requests.get("https://picsum.photos/600")
res.raise_for_status()

with Image.open(BytesIO(res.content)) as img:
    out = process(session, img, size=(256, 256), bgcolor='#F0E68C')
    out.save("output.png")

For example, an input and output might be:

input output

If you wanted to work with lots of files, your pathlib objects can be passed directly to Pillow:

from pathlib import Path

for path_in in Path(r'C:testimages').glob('*.jpg'):
    path_out = path_in.parent / f"{path_in.stem}-out.png"
    # no point processing images that have already been done!
    if path_out.exists():
        continue
    with Image.open(path_in) as img:
        out = process(session, img, size=(256, 256), bgcolor='#F0E68C')
        out.save(path_out)

Update: it’s often worth adding a check into these loops so they can be rerun and not have to process everything again. If you really do want images to be re-processed then just delete *-out.png

Answered By: Sam Mason