Ещё один способ получить картинки у себя на локальном компьютере без водяных знаков. Для этого нам нужно зарегистрироваться на fusionbrain.ai.
В личном кабинете можно генерировать фотографии и видео с помощью интерфейса сервиса. А можно воспользоваться API и запускать python-код в своём любимом Jupyter Notebook. Для этого нам понадобится API-ключи. Их можно получить в разделе, как нестранно, API. Заходим в раздел, жмём «Добавить ключ» и получаем API key и Secret key. Потом ответственно сохраняем эти ключи. Особенно Secret key, ведь если потеряем Secret key, то его больше нигде не увидишь :(
Далее сохраняем эти два ключа в файл «.env» (точка env) в формате:
YOUR_API_KEY=Ваш API KEY
YOUR_SECRET_KEY=Ваш SECRET KEY
Потом открываем Jupyter Notebook и пишем код:
Импорт библиотек
import base64
import json
import os
import requests
import time
from io import BytesIO
from dotenv import load_dotenv
from IPython.display import display, Image
Добавляем в код ключи и URL
load_dotenv('.env')
YOUR_API_KEY = os.getenv('YOUR_API_KEY')
YOUR_SECRET_KEY = os.getenv('YOUR_SECRET_KEY')
API_URL = 'https://api-key.fusionbrain.ai/'
Класс и функции для генерации изображений
Для генерации, отображения и сохранения изображений напишем небольшой class. Т.к. Dzen не поддерживает форматирование кода, то вместо пробелов проставил точки: «····».
class FusionBrainAPI:
····def __init__(self, url, api_key, secret_key):
········self.URL = url
········self.AUTH_HEADERS = {
············'X-Key': f'Key {api_key}',
············'X-Secret': f'Secret {secret_key}',
········}
····def get_pipeline(self):
········"""Получаем ID доступного пайплайна (Kandinsky)"""
········try:
············response = requests.get(self.URL + 'key/api/v1/pipelines', headers=self.AUTH_HEADERS)
············response.raise_for_status()
············data = response.json()
············if not data:
················raise Exception("Нет доступных пайплайнов. Проверьте API ключи.")
············for pipeline in data:
················if "kandinsky" in pipeline.get("name", "").lower():
····················return pipeline['id']
············raise Exception("Пайплайн Kandinsky не найден.")
············
········except Exception as e:
············raise Exception(f"Ошибка получения пайплайна: {str(e)}")
····def generate(self, prompt, style="DEFAULT", negative_prompt="", width=512, height=512, num_images=1):
········"""Генерация изображения"""
········try:
············pipeline_id = self.get_pipeline()
············params = {
················"type": "GENERATE",
················"style": style,
················"width": width,
················"height": height,
················"numImages": num_images,
················"negativePromptDecoder": negative_prompt,
················"generateParams": {
····················"query": prompt
················}
············}
············files = {
················'pipeline_id': (None, pipeline_id),
················'params': (None, json.dumps(params), 'application/json')
············}
············response = requests.post(
················self.URL + 'key/api/v1/pipeline/run',
················headers=self.AUTH_HEADERS,
················files=files
············)
············response.raise_for_status()
············return response.json()['uuid']
········except Exception as e:
············raise Exception(f"Ошибка генерации: {str(e)}")
····def check_generation(self, request_id, attempts=10, delay=5):
········"""Проверка статуса генерации"""
········try:
············while attempts > 0:
················response = requests.get(
····················self.URL + 'key/api/v1/pipeline/status/' + request_id,
····················headers=self.AUTH_HEADERS
················)
················response.raise_for_status()
················data = response.json()
················if data['status'] == 'DONE':
····················return data['result']['files']
················elif data['status'] == 'FAILED':
····················return None
················attempts -= 1
················time.sleep(delay)
············return None
········except Exception as e:
············raise Exception(f"Ошибка проверки статуса: {str(e)}")
····def get_image_bytes(self, base64_string):
········"""Конвертация Base64 в bytes"""
········if base64_string.startswith('data:image'):
············base64_string = base64_string.split(',')[1]
········return base64.b64decode(base64_string)
····def generate_and_show(self, prompt, **kwargs):
········"""Генерация + отображение в Jupyter"""
········try:
············print("⌛ Генерация начата...")
············print()
············uuid = self.generate(prompt, **kwargs)
············files = self.check_generation(uuid)
············if files:
················image_data = self.get_image_bytes(files[0])
················display(Image(image_data))
················print()
················print("✅ Готово!")
················return image_data # Возвращаем данные изображения
············else:
················print("❌ Ошибка генерации")
················return None
········except Exception as e:
············print(f"❌ Ошибка: {str(e)}")
············return None
Генерация изображения
Вставляем в ячейку следующий код:
api = FusionBrainAPI(API_URL, YOUR_API_KEY, YOUR_SECRET_KEY)
# (!) Стиль из списка https://cdn.fusionbrain.ai/static/styles/key
# Возможные значения:
# "DEFAULT" - "No style"
# "KANDINSKY" - "Kandinsky"
# "UHD" - "Detailed photo"
# "ANIME" - "Anime"
PROMPT = "киборг делает пирог" # Ваш промпт
STYLE = "KANDINSKY" # Стиль изображения
NEGATIVE_PROMPT = "размытость, низкое качество" # Негативный промпт
image_data = api.generate_and_show(
····prompt=PROMPT,
····style=STYLE,
····negative_prompt=NEGATIVE_PROMPT,
# (!) Рекомендуется использовать значения кратные 64 с каждой из сторон
····width=1024,
····height=768
)
# Сохранение файла
if image_data:
····with open(f"result_{STYLE}_{PROMPT}.jpg", "wb") as f:
········f.write(image_data)
После выполнения этого кода в папке, в которой находится скрипт появится файл: «result_KANDINSKY_киборг делает пирог.jpg». Название файла можно изменить в строке:
with open(f"result_{STYLE}_{PROMPT}.jpg", "wb") as f:
Также изображение выведется на экран:
Важные моменты
- Максимальный размер изображений: 1024×1024 px.
- Доступные пропорции сторон: квадратные (1:1), альбомные (3:2, 16:9), портретные (2:3, 9:16).
- Для лучшего качества рекомендуется использовать размеры, кратные 64 px. Например: 512×512 (1:1), 768×512 (3:2), 1024×576 (16:9), 512×768 (2:3).
- Для генерации можно использовать любой язык: русский, английский и др. Также в запросах допустимы emoji 🎨🐱👤...
Промпт с emoji: «🤖 🦄»
- Максимальная длина запроса — 1000 символов.
Отказ сервиса
❌ Сервис может временно приостанавливать приём новых заданий в следующих случаях:
- при высокой нагрузке,
- во время технического обслуживания.
❓ Как проверить доступность
Отправить GET-запрос по адресу: /key/api/v1/pipeline/{pipeline_id}/availability
Возможные ответы JSON:
{"pipeline_status": "DISABLED_BY_QUEUE" // Сервис временно недоступен}
или
{"pipeline_status": "AVAILABLE" // Сервис работает в штатном режиме}
Проверка статуса генерации
Для отслеживания выполнения конкретного задания используйте метод:
/key/api/v1/pipeline/status/{uuid}
где uuid - идентификатор задачи, полученный при создании запроса.
⚠️ Если сервис недоступен, вместо идентификатора задачи (uuid) вы получите текущий статус работы системы.
Примеры генераций
- Стиль: ANIME
- Промпт: инопланетянин в магазине
- Стиль: DEFAULT
- Промпт: дом из грибов
- Стиль: KANDINSKY
- Промпт: пчела ведёт машину
- Стиль: UHD
- Промпт: медведь программирует
Пользуйтесь! Всем творческих успехов :)
P.S. Полный рабочий код на GitHub 🐈⬛