Al usar la API de Sora 2 para generar video a partir de imágenes (Image-to-Video), el desajuste de dimensiones de la imagen de referencia es uno de los errores más comunes que enfrentan los desarrolladores. Este artículo analiza en detalle la causa raíz del error Inpaint image must match the requested width and height y ofrece 5 soluciones probadas.
Valor principal: Al terminar de leer, dominarás las reglas de validación de dimensiones de la API de Sora 2, aprenderás a usar Python (Pillow) y FFmpeg para preprocesar imágenes y solucionarás definitivamente los errores de tamaño.

Análisis de la causa del error de dimensiones en la API de Sora 2
Cuando llamas a la función de generación de video a partir de imagen de la API de Sora 2, si recibes el siguiente mensaje de error:
{
"error": {
"message": "Inpaint image must match the requested width and height",
"type": "invalid_request_error",
"param": null,
"code": null
}
}
Esto significa que la imagen de referencia (input_reference) que has subido no coincide con la resolución del video objetivo.
Reglas de coincidencia obligatoria de dimensiones de la API de Sora 2
La API de Sora 2 tiene un mecanismo estricto de validación de dimensiones:
| Elemento de validación | Requisito | Descripción |
|---|---|---|
| Coincidencia de ancho | Ancho imagen = Ancho video | Debe ser idéntico a nivel de píxel |
| Coincidencia de alto | Alto imagen = Alto video | Debe ser idéntico a nivel de píxel |
| Formatos soportados | JPEG, PNG, WebP | Los tres formatos son válidos |
| Transferencia de archivos | multipart/form-data | Debe subirse como un archivo |
Resoluciones de video soportadas por la API de Sora 2
De acuerdo con la documentación oficial de OpenAI, la API de Sora 2 soporta actualmente las siguientes resoluciones:
| Resolución | Ancho x Alto | Proporción | Escenario de uso |
|---|---|---|---|
| 720p Horizontal | 1280 x 720 | 16:9 | YouTube, video web |
| 720p Vertical | 720 x 1280 | 9:16 | TikTok, Reels, Shorts |
| 1080p Horizontal (Pro) | 1792 x 1024 | ~16:9 | Video horizontal HD |
| 1080p Vertical (Pro) | 1024 x 1792 | ~9:16 | Video vertical HD |
🎯 Nota importante: Tu imagen de referencia debe ser exactamente igual a la resolución objetivo elegida. Por ejemplo, si seleccionas 1280×720, la imagen debe tener exactamente 1280×720 píxeles; una diferencia de tan solo 1 píxel provocará un error.

5 soluciones para errores de tamaño de imagen de referencia en la API de Sora 2
Solución 1: Recorte y relleno inteligente con Python Pillow
El método ImageOps.pad() de Pillow permite procesar de forma inteligente imágenes de cualquier tamaño, manteniendo la relación de aspecto y rellenando hasta alcanzar las dimensiones del objetivo:
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
)
🚀 Inicio rápido: Te recomendamos usar la plataforma APIYI (apiyi.com) para probar rápidamente la API de Sora 2. Esta plataforma ofrece una interfaz lista para usar que permite completar la integración sin configuraciones complejas.
Solución 2: Recorte centrado con Python Pillow (preservando el sujeto)
Si prefieres conservar el contenido principal de la imagen sin añadir bordes negros de relleno, puedes optar por un recorte centrado:
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)
Solución 3: Procesamiento por lotes con la línea de comandos de FFmpeg
Para escenarios que requieren procesar imágenes de forma masiva, FFmpeg es la opción más eficiente:
Modo de recorte centrado (Cover):
# Primero escala manteniendo la proporción y luego recorta al centro para el tamaño objetivo
ffmpeg -i input.jpg -vf "scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" output_sora.jpg
Modo de relleno (Letterbox):
# Escala manteniendo la proporción original y rellena con negro las partes faltantes
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
Script para procesamiento por lotes:
#!/bin/bash
# Procesa por lotes todas las imágenes jpg del directorio actual al formato horizontal 720p de Sora 2 API
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
Solución 4: Uso del parámetro crop_bounds (Recorte integrado en la API)
La API de Sora 2 ofrece el parámetro crop_bounds, que permite especificar el área de recorte directamente a nivel de 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 # 图片作为第一帧
)
⚠️ Nota: Al usar
crop_bounds, el área recortada aún debe coincidir con la resolución del video objetivo. Se recomienda utilizarlo junto con un preprocesamiento previo.
Solución 5: Clase de utilidad completa para preprocesamiento de imágenes
Aquí tienes una clase de preprocesamiento de imágenes de nivel de producción que incluye varios modos de procesamiento:
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)
Ver código completo de ejemplo de llamada
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}")
Comparativa de modos de preprocesamiento de imagen de referencia para la API de Sora 2
Elegir el modo de preprocesamiento adecuado es crucial para el resultado final del video:

| Modo de preprocesamiento | Método de tratamiento | Ventajas | Desventajas | Escenario recomendado |
|---|---|---|---|---|
| Pad (Relleno) | Mantiene la proporción, añade bordes negros | Conserva la imagen íntegra | Puede tener bordes negros | Alta exigencia de integridad de contenido |
| Cover (Recorte) | Mantiene la proporción, recorte centrado | Sin bordes, imagen llena | Puede recortar elementos del borde | Imágenes con el sujeto centrado |
| Stretch (Estiramiento) | Estiramiento forzado | Simple y directo | Deformación de la imagen | No se recomienda su uso |
💡 Sugerencia de elección: El modo de preprocesamiento a elegir depende principalmente del contenido de tu imagen y del efecto que busques. Te sugerimos realizar pruebas en la plataforma APIYI (apiyi.com) para verificar rápidamente las diferencias de resultados entre cada modo.
Modos recomendados por escenario
| Tipo de imagen | Modo recomendado | Explicación |
|---|---|---|
| Retratos | Cover | Mantiene al sujeto centrado y completo |
| Paisajes | Pad o Cover | Elegir según la composición de la foto |
| Productos | Pad | Asegura que el producto se muestre íntegramente |
| Arte | Pad | Preserva la integridad de la obra artística |
| Capturas de UI | Cover | Por lo general, la información clave está en el centro |
Preguntas frecuentes sobre el uso de imágenes de referencia en la API de Sora 2
Q1: ¿Por qué la API de Sora 2 es tan estricta con las dimensiones de la imagen de referencia?
Sora 2 utiliza la imagen de referencia como el primer fotograma (first frame) del video; el modelo necesita partir de esta imagen para generar el contenido dinámico posterior. Si las dimensiones de la imagen no coinciden con las del video de destino, el modelo no podrá inicializar correctamente el proceso de generación. Esta es una limitación técnica diseñada por OpenAI para garantizar la consistencia en la calidad de la generación.
Al realizar llamadas a través de la plataforma APIYI (apiyi.com), te recomendamos realizar el preprocesamiento de la imagen en el lado del cliente para obtener los mejores resultados de generación.
Q2: ¿Qué formato de imagen debería elegir durante el preprocesamiento?
La API de Sora 2 es compatible con tres formatos: JPEG, PNG y WebP.
- JPEG: Recomendado para imágenes de tipo fotográfico; archivos pequeños y carga rápida.
- PNG: Ideal para casos que requieren fondos transparentes o calidad sin pérdida.
- WebP: Ofrece un buen equilibrio entre calidad y tamaño, aunque su compatibilidad es ligeramente inferior.
Sugerimos utilizar el formato JPEG con el parámetro de calidad (quality) configurado entre 90 y 95 para asegurar la calidad sin que el archivo sea demasiado pesado.
Q3: ¿Qué hacer si baja la calidad de la imagen tras el procesamiento?
La pérdida de calidad suele deberse a las siguientes razones:
- Compresión excesiva: Intenta subir la calidad de JPEG a 95.
- Escalado excesivo: Procura usar imágenes originales cuya resolución sea cercana a la del objetivo.
- Algoritmo de remuestreo: Utiliza
Image.LANCZOSen lugar deImage.NEAREST.
# Configuración de procesamiento de alta calidad
img = img.resize(target_size, Image.LANCZOS) # Usar el algoritmo Lanczos
img.save(output_path, "JPEG", quality=95) # Guardar con alta calidad
Q4: ¿Cómo puedo procesar una gran cantidad de imágenes por lotes?
Para escenarios de procesamiento masivo, recomendamos usar FFmpeg o el multihilo de 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
A través de la plataforma APIYI (apiyi.com) puedes obtener cuotas de API para procesamiento por lotes, ideales para proyectos de generación de video a gran escala.
Q5: ¿Se rechazarán las imágenes de referencia que contengan rostros humanos?
Sí, de acuerdo con las políticas de OpenAI, las imágenes que contienen rostros de personas reales podrían ser rechazadas por la API de Sora 2 actualmente. Si tu proyecto requiere videos con personas, te sugerimos:
- Usar imágenes donde no se vea el rostro con claridad.
- Usar imágenes de personajes virtuales generados por IA.
- Usar imágenes de personas con tratamientos abstractos o artísticos.
Tabla de referencia rápida de dimensiones para la API de Sora 2
Para facilitar tu trabajo, aquí tienes una tabla completa con las dimensiones correspondientes:
| Video de destino | Ancho de imagen | Alto de imagen | Parámetro size de la API |
Plataformas aplicables |
|---|---|---|---|---|
| 720p Horizontal | 1280 | 720 | "1280×720" | YouTube, Web |
| 720p Vertical | 720 | 1280 | "720×1280" | Douyin, TikTok |
| Pro Horizontal | 1792 | 1024 | "1792×1024" | Horizontal HD |
| Pro Vertical | 1024 | 1792 | "1024×1792" | Vertical HD |
📌 Nota: Las plataformas disponibles incluyen APIYI (apiyi.com), la API oficial de OpenAI, entre otras. Te recomendamos elegir plataformas con alta velocidad de respuesta y precios competitivos para tus fases de desarrollo y pruebas.
Resumen
El error de dimensiones en la imagen de referencia (pad image) de la API de Sora 2 es uno de los problemas más frecuentes a los que se enfrentan los desarrolladores. La estrategia clave para solucionarlo consiste en:
- Comprender las reglas: La imagen de referencia debe coincidir exactamente, a nivel de píxeles, con las dimensiones del vídeo de destino.
- Seleccionar el modo: Elegir entre los modos Pad o Cover dependiendo del contenido de la imagen.
- Preprocesamiento: Utilizar Python Pillow o FFmpeg para realizar un procesamiento previo.
- Validar dimensiones: Comprobar que el tamaño de la imagen sea el correcto tras el procesamiento.
Te recomendamos utilizar APIYI (apiyi.com) para validar rápidamente los resultados del preprocesamiento de imágenes y la calidad de la generación de vídeo.
Autor: APIYI Team | Para más trucos de desarrollo de IA, visita apiyi.com
Referencias:
- Documentación de la API de OpenAI Sora: Descripción de la interfaz de imagen a vídeo (Image-to-Video).
- Enlace:
platform.openai.com/docs/guides/video-generation
- Enlace:
- Documentación oficial de Pillow: Módulo de procesamiento de imágenes ImageOps.
- Enlace:
pillow.readthedocs.io/en/stable/reference/ImageOps.html
- Enlace:
- Documentación oficial de FFmpeg: Filtros de procesamiento de vídeo e imagen.
- Enlace:
ffmpeg.org/ffmpeg-filters.html
- Enlace:
