Генерация изображений через API: от текста до картинки

Генерация изображений через API: от текста до картинки

22 июня 2026 г. · Команда Hubris · 7 мин чтения

Сгенерировать изображение через API можно тем же запросом, что и текст: выберите image-модель из каталога, добавьте в запрос параметр modalities: ["image", "text"] — и модель вернёт картинку строкой base64 прямо в ответе. Останется декодировать её и записать в файл. Ниже — рабочие примеры на curl и Python, советы по промптам и актуальные цены в рублях.

Что понадобится

Генерация изображений в Hubris работает через стандартный запрос /v1/chat/completions, поэтому подойдёт любой HTTP-клиент или официальная библиотека OpenAI. Для старта нужны три вещи:

  1. Аккаунт. Регистрация на странице входа по коду из письма — пароль придумывать не нужно.
  2. API-ключ. Создаётся в разделе «Ключи» личного кабинета. Ключ начинается с sk-gw- и показывается полностью только один раз — сразу сохраните его в переменную окружения.
  3. Баланс. Пополняется в разделе «Биллинг»: по СБП, банковской картой или по счёту, если платит организация.

Подписки нет — средства списываются с баланса только за фактические генерации.

Какие модели генерируют изображения

В каталоге доступны модели двух семейств с выводом изображений (состав актуален на июнь 2026 года):

  • Nano Banana — линейка Google Gemini Image: быстрая Nano Banana 2 (google/gemini-3.1-flash-image-preview), её предшественница Nano Banana (google/gemini-2.5-flash-image) и старшая Nano Banana Pro (google/gemini-3-pro-image-preview). Сильная сторона — фотореализм и итеративное редактирование: картинку можно уточнять следующими сообщениями того же диалога.
  • GPT Image — линейка OpenAI: GPT-5 Image (openai/gpt-5-image), компактная GPT-5 Image Mini (openai/gpt-5-image-mini) и новейшая GPT-5.4 Image 2 (openai/gpt-5.4-image-2). Эти модели точно следуют длинным инструкциям из нескольких условий.

Обе линейки гибридные: возвращают и картинку, и текстовый комментарий к ней, поэтому в запросе указывается modalities: ["image", "text"]. Живой список с тарифами — в подборке моделей для изображений, а сравнить их с остальными можно в полном каталоге моделей.

Минимальный запрос: параметр modalities

Единственное отличие от текстового запроса — поле modalities. Запрос через curl выглядит так:

curl -s https://api.hubris.pw/v1/chat/completions \
  -H "Authorization: Bearer sk-gw-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-3.1-flash-image-preview",
    "modalities": ["image", "text"],
    "messages": [{"role": "user", "content": "Космический маяк среди звёзд, неоновое свечение, цифровая живопись"}]
  }'

Картинка приходит строкой base64 в поле choices[0].message.images[0].image_url.url:

{
  "id": "chatcmpl-...",
  "model": "google/gemini-3.1-flash-image-preview",
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "Готово!",
        "images": [
          {
            "type": "image_url",
            "image_url": { "url": "data:image/png;base64,iVBORw0KGgo..." }
          }
        ]
      }
    }
  ]
}

Структура полностью совместима с форматом OpenAI Chat Completions — к сообщению ассистента добавляется только массив images. Разбор остальных параметров, включая потоковую передачу, — в документации по генерации изображений.

Сохраняем картинку в файл на Python

В официальной библиотеке openai поле modalities не объявлено в типах Chat Completions, поэтому его передают через extra_body. Полный пример — от запроса до файла на диске:

import base64
from openai import OpenAI

client = OpenAI(
    base_url="https://api.hubris.pw/v1",
    api_key="sk-gw-...",
)

resp = client.chat.completions.create(
    model="google/gemini-3.1-flash-image-preview",
    messages=[{
        "role": "user",
        "content": "Маяк на скале в шторм, кинематографичный свет, цифровая живопись",
    }],
    extra_body={
        "modalities": ["image", "text"],
        "image_config": {"aspect_ratio": "16:9"},
    },
)

images = resp.choices[0].message.model_extra.get("images", [])
for i, img in enumerate(images):
    data_url = img["image_url"]["url"]        # data:image/png;base64,...
    header, b64 = data_url.split(",", 1)
    ext = header.split("/")[1].split(";")[0]  # png или jpeg
    with open(f"image_{i}.{ext}", "wb") as f:
        f.write(base64.b64decode(b64))
    print(f"Сохранено: image_{i}.{ext}")

Скрипт декодирует base64-строку, определяет расширение из заголовка data-URL и записывает каждую картинку в отдельный файл. Дополнительные библиотеки не нужны: base64 входит в стандартную поставку Python.

Фрагменты кода складываются в светящуюся рамку готового изображения

Как писать промпты для изображений

Image-модели понимают свободные описания, но предсказуемость результата сильно растёт, если соблюдать несколько правил:

  • Описывайте кадр, а не идею. Вместо «красивый город будущего» — «ночной город с высоты птичьего полёта, неоновые вывески, мокрый асфальт отражает огни».
  • Называйте стиль и технику. «Фотореализм», «плоская векторная иллюстрация», «акварель», «3D-рендер» — без указания стиля модель выберет его сама.
  • Задавайте свет и палитру. «Мягкий закатный свет», «холодные синие тона», конкретные цвета — свет влияет на результат сильнее большинства других слов.
  • Перечисляйте ограничения. «Без текста и надписей», «без людей», «без логотипов» — иначе модель может добавить лишнее.
  • Фиксируйте стиль для серии. Если картинки нужны в едином оформлении, держите неизменный стилевой «хвост» промпта и меняйте только описание сцены.
  • Соотношение сторон задавайте параметром. image_config: {"aspect_ratio": "16:9"} надёжнее, чем просьба в тексте промпта.

Если первый результат не подошёл, у моделей Nano Banana удобно работает уточнение в том же диалоге: добавьте сообщение «сделай фон темнее, убери рамку» — модель отредактирует уже созданную картинку, а не нарисует новую с нуля.

Россыпь искр-идей сходится в одну яркую точку

Сколько стоит генерация изображения

Правило простое: вы платите за каждое сгенерированное изображение. Стоимость входит в цену запроса и списывается с рублёвого баланса после успешного ответа; если модель вернула две картинки, спишется стоимость обеих. Ориентиры по статистике реальных запросов в Hubris — для стандартного разрешения, актуальны на июнь 2026 года:

МодельПримерная цена изображения
Nano Banana (google/gemini-2.5-flash-image)около 4 ₽
Nano Banana 2 (google/gemini-3.1-flash-image-preview)5,5–7 ₽
GPT-5 Image (openai/gpt-5-image)18–22 ₽
GPT-5.4 Image 2 (openai/gpt-5.4-image-2)около 22 ₽

Точная сумма зависит от модели, разрешения и параметров запроса — она видна в разделе «Расходы» личного кабинета сразу после генерации. Текущие тарифы каждой модели опубликованы на её карточке в каталоге.

Частые вопросы

Можно ли получить несколько изображений за один запрос?

Да, если модель это поддерживает: массив images в ответе может содержать несколько элементов. Цикл из примера на Python сохранит каждый в отдельный файл. Помните, что оплата начисляется за каждое изображение в ответе.

Заработает ли официальная библиотека OpenAI?

Да. Меняются только base_url на https://api.hubris.pw/v1 и ключ. Поле modalities не объявлено в типах библиотеки, поэтому в Python его передают через extra_body, а в TypeScript — приведением типа. Сам ответ разбирается стандартными средствами.

Как задать соотношение сторон и размер картинки?

Параметром image_config: поле aspect_ratio принимает значения "1:1", "16:9", "9:16", "4:3" и другие, поле image_size"1K", "2K", "4K". Это надёжнее, чем описывать формат словами в промпте.

Есть ли подписка или минимальный платёж?

Нет. Баланс пополняется на любую сумму — по СБП, картой или по счёту для юридических лиц — и расходуется только на фактические запросы. История списаний по каждой генерации доступна в личном кабинете.

Все модели из статьи доступны в Hubris — единый API, оплата в рублях.