5 способов решения ошибки размера изображения для Sora 2 API: Полное руководство по устранению ошибки Inpaint image must match

При использовании Sora 2 API для создания видео из изображений (Image-to-Video) несоответствие размера опорного изображения — одна из самых частых ошибок, с которыми сталкиваются разработчики. В этой статье мы подробно разберем первопричину ошибки Inpaint image must match the requested width and height и предложим 5 проверенных способов её решения.

Основная ценность: прочитав этот материал, вы освоите правила проверки размеров в Sora 2 API, научитесь использовать Python Pillow и FFmpeg для предобработки изображений и навсегда забудете об ошибках масштабирования.

sora-2-api-inpaint-image-size-error-solution-ru 图示


Анализ причины ошибки в Sora 2 API

Когда вы вызываете функцию Image-to-Video в Sora 2 API и видите следующее сообщение:

{
  "error": {
    "message": "Inpaint image must match the requested width and height",
    "type": "invalid_request_error",
    "param": null,
    "code": null
  }
}

Это означает, что размеры загруженного вами опорного изображения (input_reference) не совпадают с целевым разрешением видео.

Правила обязательного соответствия размеров в Sora 2 API

Sora 2 API использует строгий механизм валидации размеров:

Параметр проверки Требование Описание
Ширина Ширина фото = Ширина видео Полное попиксельное совпадение
Высота Высота фото = Высота видео Полное попиксельное совпадение
Форматы JPEG, PNG, WebP Поддерживаются все три формата
Передача файла multipart/form-data Должно загружаться именно как файл

Поддерживаемые разрешения видео в Sora 2 API

Согласно официальной документации OpenAI, Sora 2 API на данный момент поддерживает следующие разрешения:

Разрешение Ширина x Высота Соотношение Применение
720p Горизонтальное 1280 x 720 16:9 YouTube, веб-видео
720p Вертикальное 720 x 1280 9:16 Douyin, TikTok, Reels
1080p Горизонтальное (Pro) 1792 x 1024 ~16:9 HD горизонтальное видео
1080p Вертикальное (Pro) 1024 x 1792 ~9:16 HD вертикальное видео

🎯 Важное примечание: ваше опорное изображение должно идеально соответствовать выбранному целевому разрешению. Например, если вы выбрали 1280×720, изображение должно быть ровно 1280×720 пикселей. Ошибка даже в 1 пиксель приведет к отказу API.

sora-2-api-inpaint-image-size-error-solution-ru 图示


5 способов решения ошибки размеров референсного изображения для Sora 2 API

Способ 1: Умная обрезка и заполнение с помощью Python Pillow

Использование метода ImageOps.pad() в библиотеке Pillow позволяет корректно обрабатывать изображения любого размера, сохраняя соотношение сторон и добавляя поля до нужного разрешения:

from PIL import Image, ImageOps
import openai

# Sora 2 API 支持的标准分辨率
SORA_RESOLUTIONS = {
    "landscape_720p": (1280, 720),
    "portrait_720p": (720, 1280),
    "landscape_1080p": (1792, 1024),
    "portrait_1080p": (1024, 1792),
}

def preprocess_image_for_sora(image_path, target_resolution="landscape_720p"):
    """预处理图片以匹配 Sora 2 API 尺寸要求"""
    target_size = SORA_RESOLUTIONS[target_resolution]

    # 打开原图
    img = Image.open(image_path)

    # 使用 pad 方法:保持宽高比,填充黑色背景
    processed = ImageOps.pad(img, target_size, color=(0, 0, 0))

    # 保存处理后的图片
    output_path = image_path.replace(".jpg", "_sora_ready.jpg")
    processed.save(output_path, "JPEG", quality=95)

    return output_path

# 使用示例
processed_image = preprocess_image_for_sora("my_image.jpg", "landscape_720p")

# 调用 Sora 2 API - 通过 APIYI 统一接口
client = openai.OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.apiyi.com/v1"  # 使用 APIYI 统一接口
)

with open(processed_image, "rb") as f:
    response = client.videos.create(
        model="sora-2",
        prompt="A serene landscape comes to life",
        size="1280x720",
        input_reference=f
    )

🚀 Быстрый старт: Для оперативного тестирования Sora 2 API рекомендуем платформу APIYI (apiyi.com). Она предоставляет готовые к работе интерфейсы, что позволяет выполнить интеграцию без сложных настроек.

Способ 2: Центральная обрезка через Python Pillow (сохранение объекта)

Если вы хотите сохранить основной контент изображения без добавления черных полос, можно использовать центральную обрезку:

from PIL import Image

def center_crop_for_sora(image_path, target_width, target_height):
    """居中裁剪图片以匹配 Sora 2 API 尺寸要求"""
    img = Image.open(image_path)
    orig_width, orig_height = img.size

    # 计算目标宽高比
    target_ratio = target_width / target_height
    orig_ratio = orig_width / orig_height

    if orig_ratio > target_ratio:
        # 原图更宽,按高度缩放后裁剪两边
        new_height = target_height
        new_width = int(orig_width * (target_height / orig_height))
    else:
        # 原图更高,按宽度缩放后裁剪上下
        new_width = target_width
        new_height = int(orig_height * (target_width / orig_width))

    # 先缩放
    img = img.resize((new_width, new_height), Image.LANCZOS)

    # 再居中裁剪
    left = (new_width - target_width) // 2
    top = (new_height - target_height) // 2
    right = left + target_width
    bottom = top + target_height

    cropped = img.crop((left, top, right, bottom))

    output_path = image_path.replace(".jpg", f"_{target_width}x{target_height}.jpg")
    cropped.save(output_path, "JPEG", quality=95)

    return output_path

# 为横屏 720p 视频准备垫图
processed = center_crop_for_sora("my_photo.jpg", 1280, 720)

Способ 3: Пакетная обработка в командной строке через FFmpeg

Для сценариев, где требуется массовая обработка файлов, FFmpeg будет наиболее эффективным выбором:

Режим центральной обрезки (Cover):

# 先缩放保持比例,再居中裁剪到目标尺寸
ffmpeg -i input.jpg -vf "scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" output_sora.jpg

Режим заполнения (Letterbox):

# 保持原比例缩放,不足部分填充黑色
ffmpeg -i input.jpg -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2:black" output_sora.jpg

Скрипт для пакетной обработки:

#!/bin/bash
# 批量处理当前目录所有 jpg 图片为 Sora 2 API 720p 横屏格式

for file in *.jpg; do
    ffmpeg -i "$file" \
        -vf "scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" \
        -q:v 2 \
        "sora_ready_$file"
done

Способ 4: Использование параметра crop_bounds (встроенная обрезка API)

Sora 2 API поддерживает параметр crop_bounds, который позволяет указать область обрезки прямо на уровне API:

import openai

client = openai.OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.apiyi.com/v1"  # 使用 APIYI 统一接口
)

# 使用 crop_bounds 指定裁剪区域(以比例形式)
with open("full_size_image.jpg", "rb") as f:
    response = client.videos.create(
        model="sora-2",
        prompt="动态视频效果",
        size="1280x720",
        input_reference=f,
        crop_bounds={
            "left_fraction": 0.1,    # 左边裁掉 10%
            "top_fraction": 0.1,     # 顶部裁掉 10%
            "right_fraction": 0.9,   # 右边保留到 90%
            "bottom_fraction": 0.9   # 底部保留到 90%
        },
        frame_index=0  # 图片作为第一帧
    )

⚠️ Примечание: При использовании crop_bounds обрезанная область все равно должна соответствовать целевому разрешению видео. Рекомендуется сочетать этот метод с предварительной обработкой.

Способ 5: Полноценный класс-утилита для предобработки изображений

Ниже представлен инструмент предобработки изображений уровня продакшн, включающий несколько режимов работы:

from PIL import Image, ImageOps
from pathlib import Path
import io

class SoraImagePreprocessor:
    """Sora 2 API 垫图预处理工具"""

    RESOLUTIONS = {
        "1280x720": (1280, 720),
        "720x1280": (720, 1280),
        "1792x1024": (1792, 1024),
        "1024x1792": (1024, 1792),
    }

    def __init__(self, target_resolution="1280x720"):
        if target_resolution not in self.RESOLUTIONS:
            raise ValueError(f"不支持的分辨率: {target_resolution}")
        self.target_size = self.RESOLUTIONS[target_resolution]

    def pad(self, image_path, bg_color=(0, 0, 0)):
        """填充模式:保持原图比例,添加背景色填充"""
        img = Image.open(image_path)
        return ImageOps.pad(img, self.target_size, color=bg_color)

    def cover(self, image_path):
        """覆盖模式:保持原图比例,居中裁剪"""
        img = Image.open(image_path)
        return ImageOps.fit(img, self.target_size, Image.LANCZOS)

    def stretch(self, image_path):
        """拉伸模式:强制拉伸到目标尺寸(不推荐)"""
        img = Image.open(image_path)
        return img.resize(self.target_size, Image.LANCZOS)

    def to_bytes(self, img, format="JPEG", quality=95):
        """将 PIL Image 转换为字节流,用于 API 上传"""
        buffer = io.BytesIO()
        img.save(buffer, format=format, quality=quality)
        buffer.seek(0)
        return buffer

    def process_and_save(self, image_path, mode="cover", output_path=None):
        """处理并保存图片"""
        if mode == "pad":
            processed = self.pad(image_path)
        elif mode == "cover":
            processed = self.cover(image_path)
        elif mode == "stretch":
            processed = self.stretch(image_path)
        else:
            raise ValueError(f"不支持的模式: {mode}")

        if output_path is None:
            p = Path(image_path)
            output_path = p.parent / f"{p.stem}_sora_{self.target_size[0]}x{self.target_size[1]}{p.suffix}"

        processed.save(output_path, quality=95)
        return output_path

# 使用示例
preprocessor = SoraImagePreprocessor("1280x720")

# 方式1:处理并保存
output = preprocessor.process_and_save("my_image.jpg", mode="cover")
print(f"处理完成: {output}")

# 方式2:直接获取字节流用于 API 调用
img = preprocessor.cover("my_image.jpg")
image_bytes = preprocessor.to_bytes(img)
Посмотреть полный пример кода вызова
import openai
from PIL import Image, ImageOps
import io

class SoraImagePreprocessor:
    """Sora 2 API 垫图预处理工具"""

    RESOLUTIONS = {
        "1280x720": (1280, 720),
        "720x1280": (720, 1280),
        "1792x1024": (1792, 1024),
        "1024x1792": (1024, 1792),
    }

    def __init__(self, target_resolution="1280x720"):
        if target_resolution not in self.RESOLUTIONS:
            raise ValueError(f"不支持的分辨率: {target_resolution}")
        self.target_size = self.RESOLUTIONS[target_resolution]

    def cover(self, image_path):
        """覆盖模式:保持原图比例,居中裁剪"""
        img = Image.open(image_path)
        return ImageOps.fit(img, self.target_size, Image.LANCZOS)

    def to_bytes(self, img, format="JPEG", quality=95):
        """将 PIL Image 转换为字节流"""
        buffer = io.BytesIO()
        img.save(buffer, format=format, quality=quality)
        buffer.seek(0)
        return buffer


def generate_video_with_image(image_path, prompt, resolution="1280x720"):
    """
    使用预处理后的图片生成 Sora 2 视频

    Args:
        image_path: 原始图片路径
        prompt: 视频描述提示词
        resolution: 目标分辨率

    Returns:
        视频生成任务 ID
    """
    # 1. 预处理图片
    preprocessor = SoraImagePreprocessor(resolution)
    processed_img = preprocessor.cover(image_path)
    image_bytes = preprocessor.to_bytes(processed_img)

    # 2. 初始化客户端 - 通过 APIYI 统一接口
    client = openai.OpenAI(
        api_key="YOUR_API_KEY",
        base_url="https://api.apiyi.com/v1"
    )

    # 3. 调用 Sora 2 API
    response = client.videos.create(
        model="sora-2",
        prompt=prompt,
        size=resolution,
        input_reference=image_bytes,
        duration=5  # 视频时长(秒)
    )

    return response


# 完整调用示例
if __name__ == "__main__":
    result = generate_video_with_image(
        image_path="landscape_photo.jpg",
        prompt="The scene comes alive with gentle wind moving through the trees",
        resolution="1280x720"
    )
    print(f"视频生成任务已提交: {result}")

Сравнение режимов предварительной обработки референсов в Sora 2 API

Выбор правильного режима предварительной обработки критически важен для качества итогового видео:

sora-2-api-inpaint-image-size-error-solution-ru 图示

Режим обработки Метод Плюсы Минусы Когда использовать
Pad (Заполнение) Сохраняет пропорции, добавляет поля Весь исходный кадр на месте Могут появиться черные полосы Когда важна целостность каждой детали
Cover (Обрезка) Сохраняет пропорции, обрезает по центру Картинка на весь экран, без полей Края изображения могут быть отрезаны Фото с объектом в центре
Stretch (Растяжение) Принудительное растягивание Просто и прямолинейно Сильное искажение пропорций Не рекомендуется

💡 Совет по выбору: Какой режим выбрать — зависит от вашего контента и того, какой результат вы хотите получить. Мы рекомендуем протестировать разные варианты на платформе APIYI (apiyi.com), чтобы наглядно увидеть разницу и выбрать оптимальный режим.

Рекомендации для разных типов изображений

Тип изображения Рекомендуемый режим Описание
Портреты Cover Лицо остается в центре и занимает весь кадр
Пейзажи Pad или Cover Зависит от того, важен ли широкий охват или заполнение экрана
Фото товаров Pad Гарантирует, что продукт будет показан целиком
Арт и иллюстрации Pad Сохраняет композицию автора без обрезки
Скриншоты интерфейсов Cover Основная информация обычно сосредоточена в центре

Часто задаваемые вопросы по использованию референсных изображений в Sora 2 API

Q1: Почему Sora 2 API так строго требует соблюдения размеров референсного изображения?

Sora 2 использует референсное изображение в качестве первого кадра (first frame) видео. Модели необходимо начать генерацию динамического контента именно с этого кадра. Если размер изображения не совпадает с целевым разрешением видео, модель не сможет корректно инициализировать процесс генерации. Это техническое ограничение, заложенное разработчиками OpenAI для обеспечения стабильного качества результата.

При вызове API через платформу APIYI мы рекомендуем выполнять предварительную обработку изображений на стороне клиента — это позволит добиться наилучшего качества генерации.

Q2: Какой формат изображения лучше выбрать при подготовке?

Sora 2 API поддерживает три основных формата: JPEG, PNG и WebP.

  • JPEG: Рекомендуется для фотографий. Обеспечивает небольшой размер файла и быструю загрузку.
  • PNG: Подходит для сцен, где важна максимальная четкость без потерь или требуется прозрачный фон (хотя Sora пока фокусируется на полнокадровом видео).
  • WebP: Хороший баланс между качеством и весом, но иногда могут возникать вопросы совместимости со старыми библиотеками.

Оптимальный выбор — формат JPEG с параметром качества (quality) на уровне 90–95. Так вы сохраните детализацию и не перегрузите канал связи.

Q3: Что делать, если после обработки качество изображения падает?

Снижение качества обычно происходит по трем причинам:

  1. Слишком сильное сжатие: Поднимите JPEG quality до 95.
  2. Апскейлинг (растягивание): Старайтесь использовать исходники, разрешение которых максимально близко к целевому.
  3. Неудачный алгоритм ресайза: Используйте Image.LANCZOS вместо стандартного Image.NEAREST.
# Настройки высококачественной обработки
img = img.resize(target_size, Image.LANCZOS)  # Используем алгоритм Ланцоша
img.save(output_path, "JPEG", quality=95)     # Сохраняем с высоким качеством
Q4: Как обрабатывать большое количество изображений одновременно?

Для массовой обработки лучше всего использовать FFmpeg или многопоточность в Python:

from concurrent.futures import ThreadPoolExecutor
import os

def batch_process(image_dir, output_dir, resolution="1280x720"):
    preprocessor = SoraImagePreprocessor(resolution)

    def process_single(filename):
        input_path = os.path.join(image_dir, filename)
        output_path = os.path.join(output_dir, f"sora_{filename}")
        return preprocessor.process_and_save(input_path, "cover", output_path)

    image_files = [f for f in os.listdir(image_dir) if f.endswith(('.jpg', '.png'))]

    with ThreadPoolExecutor(max_workers=4) as executor:
        results = list(executor.map(process_single, image_files))

    return results

На платформе APIYI можно получить повышенные квоты на API для пакетной обработки, что отлично подходит для крупных проектов по генерации видео.

Q5: Будет ли отклонено изображение, если на нем есть человеческое лицо?

Да, согласно политике безопасности OpenAI, референсные изображения с реальными человеческими лицами на данный момент могут отклоняться Sora 2 API. Если вашему проекту нужны видео с людьми, рекомендуем:

  1. Использовать ракурсы, где лицо не видно четко (со спины, издалека).
  2. Использовать изображения виртуальных персонажей, сгенерированных ИИ.
  3. Использовать абстрактную или художественную стилизацию портретов.

Таблица соответствия размеров для Sora 2 API

Для вашего удобства мы составили шпаргалку по подбору разрешений:

Целевое видео Ширина фото Высота фото Параметр size в API Подходящие платформы
720p Горизонтальное 1280 720 "1280×720" YouTube, веб-сайты
720p Вертикальное 720 1280 "720×1280" Reels, TikTok, Shorts
Pro Горизонтальное 1792 1024 "1792×1024" HD-видео (высокое кач.)
Pro Вертикальное 1024 1792 "1024×1792" Смартфоны (высокое кач.)

📌 Совет: Вы можете использовать APIYI (apiyi.com) или официальный API OpenAI. Для разработки и тестирования рекомендуем выбирать платформы с быстрой скоростью отклика и гибкой тарификацией.


Итоги

Ошибка размеров опорного изображения (Image-to-Video) в Sora 2 API — одна из самых частых проблем, с которыми сталкиваются разработчики. Вот основные шаги для её решения:

  1. Понимание правил: размеры опорного изображения должны пиксель в пиксель совпадать с параметрами целевого видео.
  2. Выбор режима: подбирайте режим Pad (заполнение с полями) или Cover (обрезка под размер) в зависимости от содержимого картинки.
  3. Предварительная обработка: используйте библиотеки Python Pillow или FFmpeg для подготовки файлов.
  4. Проверка размеров: после обработки обязательно убедитесь, что итоговые габариты изображения соответствуют требованиям.

Рекомендуем использовать APIYI (apiyi.com) для быстрой проверки результатов предобработки изображений и качества генерации видео.


Автор: Команда APIYI | Больше советов по разработке ИИ — на apiyi.com

Справочные материалы:

  1. Документация OpenAI Sora API: Описание интерфейса Image-to-Video
    • Ссылка: platform.openai.com/docs/guides/video-generation
  2. Официальная документация Pillow: Модуль обработки изображений ImageOps
    • Ссылка: pillow.readthedocs.io/en/stable/reference/ImageOps.html
  3. Официальная документация FFmpeg: Фильтры для обработки видео и изображений
    • Ссылка: ffmpeg.org/ffmpeg-filters.html

Похожие записи