Hyperion
Hyperion

Reputation: 2625

Python PIL - AttributeError: 'NoneType' object has no attribute 'save'

I use this code to delete the border of an image using PIL:

def RemoveBlackBorders(img):
    bg = Image.new(img.mode, img.size, img.getpixel((0,0)))
    diff = ImageChops.difference(img, bg)
    diff = ImageChops.add(diff, diff, 2.0, -100)
    bbox = diff.getbbox()
    if bbox:
        return img.crop(bbox)

from here

And I use this to process all images contained in a folder:

def CropImages():
    global FOLDER
    for i in range(1, len(os.listdir(FOLDER))+1):
        image = FOLDER + "\\" + str(i) + ".jpg"
        img = Image.open(image)
        img = RemoveBlackBorders(img)
        img.save(image, "JPEG")

Everything works fine and the program does his job. The problem is that if in the folder there is a full black image (which is detected as "border"), the program stuck giving me the error:

 AttributeError: 'NoneType' object has no attribute 'save'

None of the images in the folder get cropped, even if the black image is the last one of the series. Is there a way to skip this image or delete it (which would be better)?

Upvotes: 3

Views: 16945

Answers (2)

SuperBiasedMan
SuperBiasedMan

Reputation: 9969

The Python principle of EAFP could apply here.

Basically you should have your code attempt to execute and then catch an AttributeError, telling it to skip that image.

Like this:

def CropImages():
    global FOLDER
    for i in range(1, len(os.listdir(FOLDER))+1):
        image = FOLDER + "\\" + str(i) + ".jpg"
        img = Image.open(image)
        img = RemoveBlackBorders(img)

        try:
            img.save(image, "JPEG")
        except AttributeError:
            print("Couldn't save image {}".format(image))

This just means that if it finds that error, it'll print the message and then keep looping over the rest.

Upvotes: 3

Kevin
Kevin

Reputation: 76234

Since RemoveBlackBorders returns None for images that are 100% border, you can check for None later when deciding whether to save.

def CropImages():
    global FOLDER
    for i in range(1, len(os.listdir(FOLDER))+1):
        image = FOLDER + "\\" + str(i) + ".jpg"
        img = Image.open(image)
        img = RemoveBlackBorders(img)
        if img is not None:
            img.save(image, "JPEG")

Upvotes: 1

Related Questions