JavaRush /Курси /Python SELF UA /GIF і Автоматизація обробки зображень

GIF і Автоматизація обробки зображень

Python SELF UA
Рівень 46 , Лекція 4
Відкрита

1. Автоматизація пакетної обробки зображень

Пакетна обробка зображень дозволяє виконувати однакові дії на великій кількості файлів, що економить час та зусилля. Наприклад, якщо у вас є каталог зображень, яким потрібно змінити розмір або накласти водяний знак, Pillow дозволяє створити один скрипт, який застосує операції до всіх зображень.

Зміна розміру всіх зображень в папці

У цьому прикладі ми змінимо розмір усіх зображень в папці input_images і збережемо результати в папку output_images.


import os
from PIL import Image

input_folder = "input_images/"
output_folder = "output_images/"
new_size = (800, 800)

# Переконуємося, що папка для збереження зображень існує
os.makedirs(output_folder, exist_ok=True)

# Проходимо по кожному файлу в папці input_folder
for filename in os.listdir(input_folder):
    if filename.endswith((".jpg", ".jpeg", ".png")):
        image_path = os.path.join(input_folder, filename)
        
        # Відкриваємо зображення і змінюємо його розмір
        with Image.open(image_path) as img:
            resized_img = img.resize(new_size)
            output_path = os.path.join(output_folder, filename)
            
            # Зберігаємо зображення
            resized_img.save(output_path)
            print(f"Зображення {filename} успішно змінено і збережено.")

Цей скрипт:

  1. Завантажує всі файли з папки input_images.
  2. Змінює розмір кожного зображення до 800x800 пікселів.
  3. Зберігає змінені зображення в папці output_images.

Накладення водяного знака на зображення

Накладення водяного знака на всі зображення в папці можна легко автоматизувати. У цьому прикладі додається текстовий водяний знак в правий нижній кут кожного зображення.


from PIL import ImageDraw, ImageFont

input_folder = "input_images/"
output_folder = "watermarked_images/"
watermark_text = "© My Company"

# Переконуємося, що папка для збереження зображень існує
os.makedirs(output_folder, exist_ok=True)

for filename in os.listdir(input_folder):
    if filename.endswith((".jpg", ".jpeg", ".png")):
        image_path = os.path.join(input_folder, filename)
        
        # Відкриваємо зображення і створюємо об'єкт для малювання
        with Image.open(image_path) as img:
            draw = ImageDraw.Draw(img)
            width, height = img.size
            font = ImageFont.truetype("arial.ttf", 24)
            
            # Позиція для водяного знака
            text_width, text_height = draw.textsize(watermark_text, font=font)
            x = width - text_width - 10
            y = height - text_height - 10
            
            # Додаємо водяний знак
            draw.text((x, y), watermark_text, font=font, fill=(255, 255, 255, 128))
            
            output_path = os.path.join(output_folder, filename)
            img.save(output_path)
            print(f"Водяний знак додано на зображення {filename}.")

Цей скрипт:

  1. Завантажує всі зображення з input_images.
  2. Накладає текстовий водяний знак в правий нижній кут зображення.
  3. Зберігає результати в watermarked_images.

Конвертація зображень у формат PNG

Конвертація всіх зображень в один формат також легко автоматизується. У цьому прикладі конвертуємо всі зображення з папки у формат PNG.


input_folder = "input_images/"
output_folder = "png_images/"

# Переконуємося, що папка для збереження зображень існує
os.makedirs(output_folder, exist_ok=True)

for filename in os.listdir(input_folder):
    if filename.endswith((".jpg", ".jpeg", ".bmp", ".tiff")):
        image_path = os.path.join(input_folder, filename)
        
        # Відкриваємо і конвертуємо зображення у PNG
        with Image.open(image_path) as img:
            base_filename = os.path.splitext(filename)[0]
            output_path = os.path.join(output_folder, f"{base_filename}.png")
            img.save(output_path, "PNG")
            print(f"Зображення {filename} успішно конвертовано у PNG.")

Цей скрипт конвертує зображення з форматів JPEG, BMP і TIFF у PNG, зберігаючи їх в папці png_images.

2. Робота з GIF-анімаціями

GIF-анімації представляють собою послідовність зображень, які показуються по черзі, створюючи ефект руху. За допомогою Pillow можна створювати і редагувати GIF-анімації, додавати і змінювати кадри, а також керувати швидкістю анімації.

Створення простої GIF-анімації

Щоб створити GIF-анімацію, потрібно підготувати декілька зображень (кадрів), які будуть показані послідовно. У цьому прикладі створюємо GIF з зображень в папці frames.


# Список зображень для анімації
frames_folder = "frames/"
frames = []

for filename in sorted(os.listdir(frames_folder)):
    if filename.endswith((".png", ".jpg")):
        frame_path = os.path.join(frames_folder, filename)
        frame = Image.open(frame_path)
        frames.append(frame)

# Збереження кадрів у GIF-анімацію
frames[0].save("animation.gif", save_all=True, append_images=frames[1:], duration=100, loop=0)

Цей код:

  1. Завантажує зображення з папки frames і додає їх в список frames.
  2. Створює GIF-анімацію з цих кадрів.
  3. Параметр duration=100 вказує тривалість показу кожного кадру у мілісекундах, а loop=0 задає нескінченний цикл відтворення.

Зміна швидкості анімації GIF

Щоб змінити швидкість анімації, просто змініть значення параметра duration.


# Створення анімації зі збільшеною швидкістю
frames[0].save("fast_animation.gif", save_all=True, append_images=frames[1:], duration=50, loop=0)

У цьому прикладі duration=50, що прискорює відтворення GIF вдвічі.

Додавання нових кадрів в існуючий GIF

Ви також можете відкрити існуючий GIF, додати до нього нові кадри та зберегти оновлену анімацію.


# Відкриття існуючого GIF
with Image.open("existing_animation.gif") as gif:
    frames = [frame.copy() for frame in ImageSequence.Iterator(gif)]

# Додавання нового кадру
new_frame = Image.open("new_frame.png")
frames.append(new_frame)

# Збереження оновленої анімації
frames[0].save("updated_animation.gif", save_all=True, append_images=frames[1:], duration=100, loop=0)

Цей код додає новий кадр new_frame.png в кінець анімації.

Витяг кадрів із GIF-анімації

Іноді потрібно розділити GIF-анімацію на окремі кадри. Pillow дозволяє витягувати та зберігати кожен кадр окремо.


from PIL import ImageSequence

# Відкриття GIF-анімації і витяг кадрів
with Image.open("animation.gif") as gif:
    for i, frame in enumerate(ImageSequence.Iterator(gif)):
        frame.save(f"frame_{i}.png")

Цей код зберігає кожен кадр з анімації як окреме зображення PNG.

Приклад повної роботи з GIF-анімацією та пакетною обробкою

На завершення наведемо приклад, у якому об'єднуються автоматизація пакетної обробки та робота з GIF. Ми створюємо анімацію з усіх зображень в папці, змінюючи розмір кожного кадру перед доданням.


# Завантаження зображень, зміна їх розміру і створення GIF
input_folder = "input_images/"
frames = []
new_size = (400, 400)

for filename in sorted(os.listdir(input_folder)):
    if filename.endswith((".jpg", ".jpeg", ".png")):
        image_path = os.path.join(input_folder, filename)
        with Image.open(image_path) as img:
            resized_frame = img.resize(new_size)
            frames.append(resized_frame)
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ