Inicio rápido de edición de imágenes con Qwen para editar imágenes con instrucciones de texto

Inicio rápido de edición de imágenes con Qwen para editar imágenes con instrucciones de texto

La API de edición de imágenes Qwen en Novita AI modifica una imagen existente usando una instrucción en lenguaje natural, impulsada por el modelo Qwen-Image de 20B parámetros. Este inicio rápido cubre el flujo de trabajo asíncrono completo: envía una solicitud de edición con tu imagen fuente y el prompt, recibe un ID de tarea, consulta hasta que la edición se complete y recupera la URL de la imagen editada. El endpoint es POST https://api.novita.ai/v3/async/qwen-image-edit.

Tabla de contenidos

Cuándo usar este inicio rápido

Usa esta guía cuando necesites:

  • Modificar una imagen existente mediante una instrucción de texto: cambiar fondos, intercambiar estilos, eliminar elementos, rotar objetos o ajustar prendas de vestir sin reconstruir la imagen desde cero.
  • Mantener intactas las regiones no tocadas mientras aplicas ediciones específicas. La arquitectura de doble ruta del modelo (Qwen2.5-VL para comprensión semántica + codificador VAE para preservación de apariencia) está diseñada específicamente para evitar que las ediciones se filtren en áreas que no describiste.
  • Editar texto en imágenes con precisión. Qwen Image Edit maneja reemplazos de texto bilingüe (inglés y chino) en letreros, carteles y activos de marca, preservando la fuente, el tamaño y el estilo visual circundante de una manera en la que la mayoría de los generadores de imágenes fallan.

Si estás generando una nueva imagen solo a partir de un prompt (sin necesidad de imagen de entrada), utiliza en su lugar el inicio rápido de Qwen Image txt2img. Para una visión general completa de las capacidades del modelo, puntos de referencia y arquitectura, consulta el artículo de lanzamiento de Qwen-Image en Novita AI.

Paso 1: Obtén tu clave de API de Novita

Crea una cuenta de Novita AI y navega a gestión de claves de API. Genera una clave y guárdala como variable de entorno antes de ejecutar cualquiera de los ejemplos de código a continuación:

export NOVITA_API_KEY="tu_clave_api_aqui"

Mantén la clave fuera del código del lado del cliente, bundles de frontend y control de versiones. Si la clave se ve comprometida, gírala desde la misma página de configuración.

Paso 2: Confirma el endpoint y el modelo

Elemento Valor
Endpoint de edición POST https://api.novita.ai/v3/async/qwen-image-edit
Endpoint de consulta de resultados GET https://api.novita.ai/v3/async/task-result?task_id=<id>
Modelo Qwen Image Edit (20B MMDiT, arquitectura de doble ruta)
Documentación de la API Referencia de Qwen Image Edit de Novita AI

La API es asíncrona. La llamada de edición devuelve un task_id inmediatamente; consultas el endpoint de resultado hasta que el estado sea TASK_STATUS_SUCCEED. Este es el mismo patrón de dos pasos utilizado por todos los endpoints de generación de imágenes de Novita AI, incluido el endpoint txt2img.

El precio es de $0.02 por imagen. Verifica la tarifa actual en la página de precios de Novita AI antes de construir un modelo de costos.

Paso 3: Envía tu primera solicitud de edición

Haz un POST al endpoint de edición con tu imagen fuente y la instrucción de edición:

curl -s -X POST https://api.novita.ai/v3/async/qwen-image-edit \
  -H "Authorization: Bearer $NOVITA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Cambia el fondo a un paisaje de montañas nevadas",
    "image": "https://example.com/my-portrait.jpg"
  }'

Una respuesta exitosa 200 devuelve:

{
  "task_id": "abc123..."
}

Guarda el task_id — lo necesitas para recuperar la imagen editada.

Paso 4: Consulta tu resultado

Haz un GET al endpoint de resultado de la tarea con el task_id como parámetro de consulta:

curl -s "https://api.novita.ai/v3/async/task-result?task_id=abc123..." \
  -H "Authorization: Bearer $NOVITA_API_KEY"

Sigue consultando hasta que el campo task_status sea TASK_STATUS_SUCCEED:

{
  "task_status": "TASK_STATUS_SUCCEED",
  "images": [
    {
      "image_url": "https://...",
      "image_url_ttl": "86400",
      "image_type": "JPEG"
    }
  ]
}

La image_url expira después de la ventana TTL (normalmente 24 horas). Descarga y almacena el resultado en tu propio almacenamiento de objetos si necesitas acceso a largo plazo.

Valores de estado a manejar:

Estado Significado
TASK_STATUS_QUEUED La solicitud está en espera en la cola; sigue consultando
TASK_STATUS_PROCESSING La edición está en progreso; sigue consultando
TASK_STATUS_SUCCEED Completa; lee la imagen editada de images[0].image_url
TASK_STATUS_FAILED La generación falló; revisa el campo de error para la razón

Paso 5: Verifica precios, límites y errores comunes

Precio: $0.02 por imagen (verifica en la página de precios).

Límites de tasa: Consulta la referencia de la API para conocer los límites de tasa actuales. Si recibes un 429, reduce tu tasa de solicitudes e implementa un backoff exponencial en los reintentos.

Errores HTTP comunes:

Código de estado Causa probable
400 Cuerpo de solicitud mal formado — falta prompt o image, formato de imagen no válido o tamaño de entrada no soportado
401 Clave de API faltante o no válida — confirma el formato Authorization: Bearer <clave>
429 Límite de tasa excedido — agrega lógica de backoff y reintento
500 Error del lado del servidor — reintenta después de una breve pausa

Si el estado de la tarea es TASK_STATUS_FAILED, la respuesta generalmente incluye un mensaje de error. Las razones comunes incluyen formatos de imagen no soportados, imágenes que exceden los límites de tamaño o prompts que activan filtros de seguridad de contenido.

Ejemplo en Python

Este script envía una solicitud de edición, consulta hasta que se completa e imprime la URL de la imagen de salida:

import os
import time
import requests

API_KEY = os.environ["NOVITA_API_KEY"]
BASE_URL = "https://api.novita.ai/v3/async"


def submit_edit(image: str, prompt: str, seed: int | None = None) -> str:
    payload: dict = {"prompt": prompt, "image": image}
    if seed is not None:
        payload["seed"] = seed
    response = requests.post(
        f"{BASE_URL}/qwen-image-edit",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        json=payload,
    )
    response.raise_for_status()
    return response.json()["task_id"]


def poll_result(task_id: str, interval: float = 2.0, timeout: float = 120.0) -> dict:
    deadline = time.time() + timeout
    while time.time() < deadline:
        response = requests.get(
            f"{BASE_URL}/task-result",
            headers={"Authorization": f"Bearer {API_KEY}"},
            params={"task_id": task_id},
        )
        response.raise_for_status()
        data = response.json()
        status = data.get("task_status", "")
        if status == "TASK_STATUS_SUCCEED":
            return data
        if status == "TASK_STATUS_FAILED":
            raise RuntimeError(f"La tarea de edición falló: {data}")
        time.sleep(interval)
    raise TimeoutError(f"La tarea {task_id} no se completó en {timeout}s")


if __name__ == "__main__":
    task_id = submit_edit(
        image="https://example.com/product-photo.jpg",
        prompt="Cambia la chaqueta a una chaqueta de cuero roja, preserva el fondo",
    )
    print(f"ID de tarea: {task_id}")

    result = poll_result(task_id)
    for img in result["images"]:
        print(img["image_url"])

Ejemplo en cURL

Flujo de trabajo de dos comandos usando jq para el análisis JSON:

#!/bin/bash
# Paso 1: enviar la solicitud de edición
TASK_ID=$(curl -s -X POST https://api.novita.ai/v3/async/qwen-image-edit \
  -H "Authorization: Bearer $NOVITA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Convierte a estilo de acuarela, preserva el sujeto y la composición",
    "image": "https://example.com/landscape.jpg"
  }' | jq -r '.task_id')

echo "ID de tarea: $TASK_ID"

# Paso 2: consultar hasta completar
while true; do
  RESULT=$(curl -s "https://api.novita.ai/v3/async/task-result?task_id=$TASK_ID" \
    -H "Authorization: Bearer $NOVITA_API_KEY")
  STATUS=$(echo "$RESULT" | jq -r '.task_status')
  echo "Estado: $STATUS"
  if [ "$STATUS" = "TASK_STATUS_SUCCEED" ]; then
    echo "$RESULT" | jq -r '.images[].image_url'
    break
  elif [ "$STATUS" = "TASK_STATUS_FAILED" ]; then
    echo "Tarea fallida:"
    echo "$RESULT" | jq .
    exit 1
  fi
  sleep 2
done

Instala jq con apt install jq (Debian/Ubuntu) o brew install jq (macOS) si aún no está presente.

Parámetros clave

Parámetro Tipo Obligatorio Valor predeterminado Descripción
prompt string Instrucción en lenguaje natural que describe la edición deseada
image string Imagen fuente como URL o cadena codificada en base64
seed integer No aleatorio Semilla fija para salidas reproducibles en múltiples ejecuciones
output_format string No jpeg Formato de salida — consulta la documentación de la API para valores aceptados

Escribir prompts efectivos: La especificidad importa. “Cambia el texto en la valla publicitaria a ‘Summer Sale’” le da al modelo una tarea clara y acotada. “Mejora la imagen” no lo hace. Cuando quieras cambiar un elemento y mantener todo lo demás intacto, nombra lo que deseas preservar: “cambia el color de la chaqueta a rojo, mantén el fondo y el rostro sin cambios”. Esto ayuda a la ruta del codificador VAE a hacer su trabajo de fijar las regiones no tocadas.

Usar seed para iteración: Al ajustar un prompt, fijar la semilla te permite comparar ediciones directamente — la variación en la salida proviene del cambio en tu prompt, no del muestreo aleatorio. Una vez que encuentres un prompt que funcione, elimina la restricción de la semilla si deseas diversidad en las salidas entre múltiples ediciones.

Casos de uso típicos

Reemplazo de fondo: “Reemplaza el fondo con un estudio blanco minimalista” — Qwen Image Edit preserva los bordes del sujeto y la iluminación mientras cambia el entorno. Funciona de manera confiable cuando el sujeto tiene un límite claro contra el fondo original.

Texto en imágenes: Reemplazar letreros de tiendas, titulares de carteles o etiquetas de productos con texto nuevo — incluyendo chino e inglés. El modelo preserva el estilo de la fuente y el contexto visual circundante mejor que los enfoques generativos de inpainting que tienden a regenerar toda la región.

Conversión de estilo: “Convierte a estilo de pintura al óleo” o “haz que parezca un boceto a lápiz” aplicado a una imagen fuente en lugar de describirla desde cero. La ruta del codificador VAE preserva la composición original y la ubicación de los objetos mientras que el prompt impulsa la transformación del estilo.

Cambios a nivel de objeto: Intercambiar prendas de vestir, cambiar colores de elementos específicos, agregar o quitar accesorios. La instrucción debe nombrar el elemento específico que se está cambiando para evitar que la edición afecte regiones adyacentes.

Conversión de IP y rotación de objetos: El modelo admite cambios de síntesis de vista (por ejemplo, rotar un objeto para mostrar un ángulo diferente) y conversión entre estilos visuales para imágenes de personajes o productos — casos de uso documentados en la descripción general de Qwen-Image-Edit en Novita AI.

Solución de problemas

La salida parece sin cambios: La instrucción probablemente está poco especificada. Hazla más explícita sobre qué elemento se debe atacar: “Cambia el color del coche de azul a rojo” en lugar de “hazlo rojo”.

Las ediciones no deseadas se extienden a áreas no previstas: Para ediciones locales muy específicas, incluye lenguaje de preservación explícito en tu prompt: “solo cambia X, deja Y intacto”. Los prompts demasiado abiertos le dan al modelo libertad para reinterpretar toda la composición.

La tarea se completa pero la URL de la imagen devuelve 403 o 404: El campo image_url_ttl (en segundos) te indica cuánto tiempo es válida la URL. Si consultas la URL después del TTL, la URL ha expirado. Descarga la imagen inmediatamente después de una consulta exitosa.

401 No autorizado: Verifica que el formato del encabezado Authorization sea exactamente Bearer <clave> con un espacio después de Bearer. Confirma que la clave esté activa y no haya sido revocada en la consola de Novita AI.

Las tareas se agotan constantemente: La edición de imágenes lleva más tiempo que la generación de texto — normalmente de 15 a 60 segundos bajo carga normal. Si las tareas superan rutinariamente tu tiempo de espera, aumenta la ventana de consulta antes de tratarlo como un fallo.

Preguntas frecuentes

¿La imagen fuente permanece en los servidores de Novita?

Tu imagen se carga en la API de Novita AI a través de HTTPS y se procesa en su infraestructura. Revisa las políticas de manejo de datos de Novita AI antes de enviar imágenes con información personal sensible, datos de salud privados o contenido confidencial.

¿Puedo usar imágenes codificadas en base64 en lugar de una URL?

Sí. Pasa la cadena base64 sin procesar en el campo image. Consulta la referencia de la API para conocer los límites de tamaño en los payloads base64.

¿Hay un parámetro de semilla para consistencia?

Sí — el parámetro opcional seed fija el estado aleatorio para que el mismo prompt e imagen produzcan resultados consistentes. Útil para iterar en la redacción del prompt sin ruido de salida debido a un nuevo muestreo.

¿Puedo usar este endpoint para trabajos por lotes?

Sí. Envía múltiples solicitudes de edición en paralelo y recoge los valores task_id, luego consúltalos concurrentemente. Cada solicitud es independiente.

¿Cuál es la diferencia entre esto y el endpoint Qwen Image txt2img?

El endpoint de edición requiere una imagen fuente y produce una versión modificada de ella. El endpoint txt2img genera una imagen completamente a partir de un prompt de texto — sin imagen de entrada. Usa el endpoint de edición cuando tengas contenido existente que quieras modificar; usa txt2img cuando estés creando desde cero.

Artículos recomendados