I am assisting in making a wiki for an old game, and we ripped the avatar GIFs from the games shop and want to have a catalog of them. What I need to do is to crop all the borders which are identical from 3,170 GIFs and maybe make background transparent.

I haven’t used python in years, but I managed to cobble up something that almost works as a single image test, only issue is that it crops and outputs only the first frame:

from PIL import Image

if __name__ == "__main__":
    input_loc = "AvatarShopImages/80001.gif"
    output_loc = "Output/80001.gif"
    im = Image.open(input_loc)
    im = im.crop((4, 4, 94, 94))
    im.save(output_loc)

If it looks weird, it is because I copy/pasted some code and edited a lot out of it.

2 points
*

As far as i know, for pillow to do what you want you would need to

  • Take a gif and split it in to frames
  • Edit each frame individually
  • Put frames back together as a gif
  • Repeat for every gif

    It can be done automagically like you want, but if you’re not interested in learning python maybe the XnConvert or ffmpeg comment above might be the way to go for ease of use.
permalink
report
reply
1 point
*

As others have suggested, ffmpeg is a great cli tool. If you aren’t comfortable with the terminal you can do it via python like this:

import os
import sys
import subprocess


def crop_media(file_name: str, w: int, h: int, x: int, y: int, new_dir: str) -> None:
    try:
        subprocess.run(f'ffmpeg -i "{file_name}" -vf "crop={w}:{h}:{x}:{y}" temp.gif -y',
                           shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        os.rename('temp.gif', os.path.join(new_dir, file_name))
    # Print the error and continue with other gifs, remove try block if you want a complete stop
    except subprocess.CalledProcessError as e:
        print(e)
    except KeyboardInterrupt:
        print('KeyboardInterrupt, cleaning up files...')
        os.remove('temp.gif')
        sys.exit(0)


def crop_directory(directory: str, w: int, h: int, x: int, y: int, new_dir: str) -> None:
    for root, _, files in directory:
        for file in files:
            if not file.endswith('.gif'):
                continue
            if os.path.isfile(os.path.join(new_dir, file)):
                print(f'{file} already exists in {new_dir}, skipping...')
                continue

            file_path = os.path.normpath(os.path.join(root, file))
            crop_media(file_path, w, h, x, y, new_dir)


if __name__ == '__main__':
    width = 0
    height = 0
    x_offset = 0
    y_offset = 0
    gif_directory = ''
    new_directory = ''
    crop_directory(gif_directory, width, height, x_offset, y_offset, new_directory)

This should go through every file in the directory and subdirectories and call the ffmpeg command on each .gif. With new_directory you can set a directory to store every cropped .gif. The ffmpeg command is based on johnpiers suggestion.

The script assumes unique filenames for each gif and should work with spaces in the filenames. If they aren’t unique, you can just remove the new_directory part, but you will then lose the original gif that you cropped.

permalink
report
reply
3 points

@Shady_Shiroe

Open GIMP
Go to “File” > “Open” and select your GIF.
Select the “Crop Tool” from the toolbox.
Adjust the crop area to your desired size.
Click the “Crop” button.
Go to “File” > “Export As” and choose GIF as the format. Save your cropped GIF.

FFmpeg
Use the following command to crop the GIF, replacing input.gif with your GIF’s filename and specifying the crop dimensions:

ffmpeg -i input.gif -vf “crop=w:h:x:y” output.gif

permalink
report
reply
3 points

Let me clarify, there are 3 THOUSAND GIFs that need to be cropped

permalink
report
parent
reply
3 points
*

If they’re all the same size and need cropped to the same size you could drop them all in one folder and run the ffmpeg command with *.gif. That should do all of them.

You’d have to find a way to automate the output though.

permalink
report
parent
reply
7 points

for i in $( ls *.gif ); do fmpeg -i $i -vf “crop=w:h:x:y” cropped_$i; done

This runs on Linux/Mac or on WSL on windows Make sure there are no spaces in the filenames.

permalink
report
parent
reply
3 points

Check out Xnconvert, it’s completely free and was made for things like this. You can do a bunch of different actions on a set of images and specify where and how to save the output files.

permalink
report
reply

Python

!python@programming.dev

Create post

Welcome to the Python community on the programming.dev Lemmy instance!

📅 Events
Past

November 2023

October 2023

July 2023

August 2023

September 2023

🐍 Python project:
💓 Python Community:
✨ Python Ecosystem:
🌌 Fediverse
Communities
Projects
  • Pythörhead: a Python library for interacting with Lemmy
  • Plemmy: a Python package for accessing the Lemmy API
  • pylemmy pylemmy enables simple access to Lemmy’s API with Python
  • mastodon.py, a Python wrapper for the Mastodon API
Feeds

Community stats

  • 719

    Monthly active users

  • 438

    Posts

  • 2.2K

    Comments