Прочитав несколько уроков, я пришел к такому решению:
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageSequence
from matplotlib.widgets import RectangleSelector
class ImageCutter:
def __init__(self, file):
self.file = file
self.img = Image.open(file)
self.frames = [np.array(frame.copy().convert("RGB"))
for frame in ImageSequence.Iterator(self.img)]
self.pos = np.array([0,0,0,0])
def crop(self):
self.pos = self.pos.astype(int)
self.cropped_imgs = [frame[self.pos[1]:self.pos[3], self.pos[0]:self.pos[2]]
for frame in self.frames]
self.save()
def save(self):
self.imgs_pil = [Image.fromarray(np.uint8(img))
for img in self.cropped_imgs]
self.imgs_pil[0].save(self.file+"_cropped.gif",
save_all=True,
append_images=self.imgs_pil[1:],
duration=16,
loop=0)
data = ImageCutter("final.gif")
fig, ax = plt.subplots(1)
ax.axis("off")
plt.imshow(data.frames[0])
def onselect(eclick, erelease):
"eclick and erelease are matplotlib events at press and release."
data.pos = np.array([eclick.xdata, eclick.ydata, erelease.xdata, erelease.ydata])
def onrelease(event):
data.crop()
cid = fig.canvas.mpl_connect('button_release_event', onrelease)
RS = RectangleSelector(ax, onselect, drawtype='box')
Вы помещаете свое имя файла в экземпляр ImageCutter
, и оно будет отображать первый кадр, позволяя вам выбрать прямоугольник с помощью мыши, который определяет область для обрезки. После того, как вы определили область, щелкните где-нибудь на изображении, и программа сохранит обрезанный gif в вашей рабочей папке.
Вместо виджета вы можете использовать свой собственный Rectangle