выводим набор картинок jpg

   выводим набор картинок  jpg   
   как  слайд шоу фреймов в формате
   mp4,  gif   и   WebP



from moviepy.editor import ImageSequenceClip
import glob
import os

# Путь к текущей папке
current_dir = '.'
jpg_files = sorted(glob.glob(os.path.join(current_dir, '*.jpg')))

if not jpg_files:
    print("Нет JPG-файлов.")
    exit()

# Создать клип из изображений с fps=1 (1 кадр/сек)
clip = ImageSequenceClip(jpg_files, fps=1)
clip.write_videofile('output.mp4', codec='libx264', audio=False)
print("Видео MP4 создано: output.mp4 (полная цветность)")





   **



from PIL import Image
import glob
import os

# Путь к текущей папке (где лежат JPG)
current_dir = '.'

# Найти все JPG-файлы в текущей папке и отсортировать по имени (алфавитно)
jpg_files = sorted(glob.glob(os.path.join(current_dir, '*.jpg')))

# Проверить, есть ли файлы
if not jpg_files:
    print("Нет JPG-файлов в текущей папке.")
    exit()

# Открыть все изображения (сохраняем оригинальный режим, обычно RGB)
frames = [Image.open(file) for file in jpg_files]

# Найти максимальную ширину и высоту среди всех кадров
max_width = max(img.width for img in frames)
max_height = max(img.height for img in frames)

# Создать новые кадры: каждый оригинал размещается по центру на белом фоне размера max_width x max_height
# Это сохраняет aspect ratio и оригинальные размеры без масштабирования
new_frames = []
white_bg = (255, 255, 255)  # Белый фон (можно изменить на (0,0,0) для чёрного или (0,0,0,0) для прозрачного RGBA)
for img in frames:
    # Создать новое изображение с максимальными размерами и белым фоном (RGB)
    new_img = Image.new('RGB', (max_width, max_height), white_bg)
    # Разместить оригинал по центру без изменения размера или пропорций
    x_offset = (max_width - img.width) // 2
    y_offset = (max_height - img.height) // 2
    new_img.paste(img, (x_offset, y_offset))
    new_frames.append(new_img)

# Сохранить как анимированный WebP с lossless (без потерь, сохраняет 100% цветность)
try:
    new_frames[0].save(
        'output.webp',
        save_all=True,
        append_images=new_frames[1:],
        duration=1000,  # Задержка 1000 мс = 1 секунда между кадрами
        loop=0,         # Бесконечный цикл (0 = бесконечно; для одного проигрывания loop=1)
        lossless=True,  # Без потерь — сохраняет полную цветность JPG
        quality=100     # Максимальное качество (для lossless игнорируется, но полезно)
    )
    print("Анимированный WebP создан: output.webp (с полной цветностью JPG)")
except Exception as e:
    print(f"Ошибка при создании WebP: {e}")
    print("Убедитесь, что Pillow установлен с поддержкой WebP (pip install pillow[webp]).")




      **



Проблема с "нарушенной цветовой палитрой" типична для формата GIF:

JPG-файлы хранят цвета в полном RGB-пространстве (миллионы оттенков).
GIF использует палитру из максимум 256 цветов, поэтому Pillow автоматически "квантует" (сжимает) цвета при сохранении, что может привести к потере деталей, banding (полосам) в градиентах или искажению ярких/темных тонов.
Дополнительно, прозрачный фон (RGBA) в моём предыдущем коде может усугублять это, так как GIF обрабатывает прозрачность как один "прозрачный" цвет в палитре, что иногда вызывает артефакты.
Я исправил код, чтобы максимально сохранить цвета:

Перешёл на адаптивную палитру (Image.ADAPTIVE), которая подбирает 256 лучших цветов под ваши изображения (вместо дефолтной веб-палитры).
Установил colors=256 (максимум для GIF).
Изменил фон на белый (solid, непрозрачный) вместо прозрачного — это упрощает обработку и лучше сохраняет цвета (прозрачность в GIF часто портит палитру). Если нужен прозрачный фон, я могу доработать, но для JPG это редко требуется.
Добавил конвертацию в RGB перед paste, чтобы избежать проблем с режимами.
optimize=False — оптимизация иногда дополнительно сжимает палитру, ухудшая цвета.
Если цвета всё равно не идеальны (GIF — не лучший формат для фото с богатой палитрой), рассмотрите альтернативы в конце.

Исправленный Python-скрипт
Скопируйте в файл create_gif.py и запустите в папке с JPG (как раньше: python create_gif.py).

from PIL import Image
import glob
import os

# Путь к текущей папке (где лежат JPG)
current_dir = '.'

# Найти все JPG-файлы в текущей папке и отсортировать по имени (алфавитно)
jpg_files = sorted(glob.glob(os.path.join(current_dir, '*.jpg')))

# Проверить, есть ли файлы
if not jpg_files:
    print("Нет JPG-файлов в текущей папке.")
    exit()

# Открыть все изображения и конвертировать в RGB (для совместимости)
frames = [Image.open(file).convert('RGB') for file in jpg_files]

# Найти максимальную ширину и высоту среди всех кадров
max_width = max(img.width for img in frames)
max_height = max(img.height for img in frames)

# Создать новые кадры: каждый оригинал размещается по центру на белом фоне размера max_width x max_height
# Это сохраняет aspect ratio и оригинальные размеры без масштабирования
new_frames = []
white_bg = (255, 255, 255)  # Белый фон (можно изменить на (0,0,0) для чёрного)
for img in frames:
    # Создать новое изображение с максимальными размерами и белым фоном (RGB)
    new_img = Image.new('RGB', (max_width, max_height), white_bg)
    # Разместить оригинал по центру без изменения размера или пропорций
    x_offset = (max_width - img.width) // 2
    y_offset = (max_height - img.height) // 2
    new_img.paste(img, (x_offset, y_offset))
    new_frames.append(new_img)

# Сохранить как GIF с улучшенной палитрой для сохранения цветов
try:
    # Конвертировать первый кадр в палитровый режим с адаптивной палитрой (для всего GIF)
    first_frame = new_frames[0].convert('P', palette=Image.ADAPTIVE, colors=256)
   
    first_frame.save(
        'output.gif',
        save_all=True,
        append_images=[frame.convert('P', palette=Image.ADAPTIVE, colors=256) for frame in new_frames[1:]],
        duration=1000,  # Задержка 1000 мс = 1 секунда между кадрами
        loop=0,         # Бесконечный цикл (0 = бесконечно; для одного проигрывания loop=1)
        optimize=False, # Отключаем оптимизацию, чтобы не сжимать палитру дополнительно
        palette=Image.ADAPTIVE,  # Адаптивная палитра для всего файла
        colors=256      # Максимум 256 цветов для лучшего качества
    )
    print("GIF-анимация создана: output.gif (с улучшенной палитрой)")
except Exception as e:
    print(f"Ошибка при создании GIF: {e}")
    print("Убедитесь, что все изображения корректны и Pillow установлен.")




Что изменилось и почему это помогает
Конвертация в 'RGB' при открытии: Убеждаемся, что все JPG в одном режиме (RGB), без альфа-канала, чтобы избежать артефактов.
Белый фон вместо прозрачного:
Создаём Image.new('RGB', ..., white_bg) — это даёт непрозрачный фон, который лучше интегрируется в палитру GIF.
Меньшие кадры будут "плавать" на белом фоне, но цвета оригиналов останутся ближе к исходным (без конфликта с прозрачностью).
Если хотите другой цвет фона (например, чёрный: (0, 0, 0)), просто измените white_bg.
Конвертация в 'P' (палитровый) с Image.ADAPTIVE:
Перед сохранением каждый кадр конвертируется в палитровый режим с адаптивной палитрой, которая анализирует цвета в изображении и выбирает наиболее подходящие 256 оттенков. Это минимизирует потерю качества по сравнению с дефолтной палитрой.
colors=256: Полный набор цветов для GIF — даёт наилучший результат.
Результат: Цвета должны быть ближе к оригинальным JPG. Если изображения простые (не фото с градиентами), разница будет минимальной. Тестируйте: сравните output.gif с оригинальными JPG в просмотрщике.


Если цвета всё ещё не устраивают:
Прозрачный фон: Если нужен именно он (для наложения на другой фон), замените Image.new('RGB', ...) на Image.new('RGBA', (max_width, max_height), (0,0,0,0)), а paste используйте с маской: new_img.paste(img.convert('RGBA'), (x_offset, y_offset), img.convert('RGBA')). Затем в save добавьте transparency=0 (индекс прозрачного цвета). Но это может снова ухудшить палитру — протестируйте.

Качество: Добавьте quality=95 в save() для большего размера файла, но лучшего сжатия (хотя для палитры это влияет слабо).
Тестирование: Откройте GIF в разных программах (браузер, Photoshop, GIMP) — иногда просмотрщики по-разному интерпретируют палитру.

Альтернативы GIF, если цвета критичны:
APNG (анимированный PNG): Поддерживает full RGB + прозрачность без потери цветов. Измените расширение на .png и используйте format='PNG' в save() (но не все браузеры поддерживают).
WebP: Современный формат с анимацией и хорошим сжатием. Установите pip install pillow[webp], затем format='WEBP', lossless=True для без потерь.
Видео (MP4): Если не обязательно GIF, используйте moviepy (pip install moviepy): создаст видео с полными цветами.

Пример:
from moviepy.editor import ImageSequenceClip
clip = ImageSequenceClip([img.filename for img in frames])  # Или пути
clip.write_gif('output.gif', fps=1)  # Или write_videofile('output.mp4', fps=1)

Если проблема persists: Поделитесь скриншотом "до/после" или описанием (какие цвета искажаются: кожа, небо?), версией Python/Pillow (pip show pillow), и примерами JPG (если возможно). Это поможет точнее доработать!
Теперь GIF должен выглядеть гораздо лучше. Если что-то не так, дайте знать! ;

не тот формат цветности нужно сохранить формат картинок исходных цветов jpg

Проблема с сохранением цветности JPG в GIF
Спасибо за уточнение! Вы правы: GIF не может сохранить полную цветность JPG (RGB с миллионами оттенков), потому что он использует ограниченную палитру из максимум 256 цветов.
Даже с адаптивной палитрой (как в моём предыдущем коде) происходит потеря качества — цвета "квантуются" (сжимаются), что приводит к banding, искажению градиентов или потере насыщенности. Это фундаментальное ограничение формата GIF, предназначенного для простых изображений, а не для фото с богатой палитрой.

Чтобы сохранить исходную цветность JPG без потерь, нужно перейти на другой формат анимации.
Вот подходящие альтернативы (все поддерживают полную RGB/цветность, как в JPG):

WebP (рекомендую как лучший баланс): Современный формат от Google, поддерживает анимацию с lossless (без потерь) или высоким качеством. Браузеры и многие программы его понимают. Pillow может создавать анимированные WebP.
APNG (анимированный PNG): Полная цветность + прозрачность, но Pillow не поддерживает анимацию APNG напрямую (только статические PNG).

Можно использовать внешние инструменты вроде apngasm, но это усложнит.
MP4 (видео): Полная цветность, но не изображение — это видео. Используйте moviepy для создания видео из кадров с fps=1 (1 кадр в секунду). Идеально для точного сохранения цветов.
Я предоставлю код для WebP (lossless) — это closest к GIF, но с сохранением цветов. Если нужно MP4, добавлю в конце.

Исправленный Python-скрипт для анимированного WebP (с lossless для точного сохранения цветов)


Рецензии