Найти тему
Генератор идей

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

Всем привет,недавно появилась идея написать бота в телеграмме для генерации изображения,но никак не мог найти материалов для этого,покопавшись наткнулся на проект Stable Diffusion.

Stable Diffusion
Stable Diffusion

Данный проект имеет открытый код. Что как раз нам и нужно для написания бота для генерации изображения.

Первое что нам понадобиться для создания нашего проекта это API ключ с Stable Diffusion и API ключ для будущего телеграмм бота.

1.Получим ключ Stable Diffusion.

Для этого перейдем по ссылке https://stablediffusionapi.com/ и зарегистрируемся на проекте.

Главная страница Stable Diffusion
Главная страница Stable Diffusion

После прохождения регистрации нужно на жать на кнопку API settings,она находиться на верхней панели.

-3

После мы попадаем в настройки API ключа.Для получения нашего API ключа ну жно нажать на боковой панели на API keys.

API Keys
API Keys

Здесь нужно дать название нашему API ключу и нажать на кнопку Create new key.

-5

После этого нажимаем на кнопку View API Keys и копируем его.

Теперь перейдем в Pycharm и создадим новый файл с названием 'config',в даном файле у нас будет всего две переменные для хранения наших API ключей это делается для того чтобы они не хранились прямо в коде.

Далее создаем переменную API_AI и вставляем туда наш ключ от ИИ.

-6

Отлично,теперь перейдем в телеграмм бота Bot_father и создадим там нашего бота.Для удобства держите ссылочку на бота @BotFather.

Пишем боту команду /newbot и следуем инструкциям в конце получаем сообщение с API ключом от нашего бота.

Ключ выглядит примерно так 6339942231:AAHl8Ld33SYzUcH8w0Jm4Yzb9Z25HrFXaow

*Не беспокойтесь я дал старый не рабочий API ключ*

Далее снова переходим в Pycharm и в файле config создаем вторую переменную API_bot в которую так же вставляем полученный нами ключ.

-7

Все отлично подготовку мы сделали перейдем к созданию самого бота.

2.Написание бота

Для этого можно создать новый файл либо же работать прям в main,для нас это не важно. Это зависит от вас.

Для работы бота мы будем использовать библиотеку TeleBot,так как по моему мнению это самая простая в освоении и в принципе самая понятная библиотека для работы с ботами.

Так же нам понадобятся следующие библиотеки в принципе для работы ИИ и некоторых задач.

1. Requests - для отправки post запроса на сервер с ИИ
2. Json -
для создания json файла с конфигурацией нашей картинки и дальнейшего получения ответа от сервера
3.Translate -
для перевода на английский язык запроса нашего пользователя
4.Pillow,IO -
для преобразования ссылки с изображением в картинку

Для начала давайте установим все эти библиотеки. Для этого переходим в терминал и прописываем следующие команды.

pip install telebot
pip install request
pip install translate
pip install pillow

После установки импортируем их в наш проект

-8
import requests
import json
from telebot import TeleBot
from translate import Translator
from PIL import Image
import io

Отлично,теперь нам нужно импортировать наш файл с API ключами. Для этого мы напишем:

from config import API_AI,API_bot

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

-9

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

-10
url = "https://stablediffusionapi.com/api/v3/text2img"
bot = TeleBot(API_bot)

Далее для активации нашего бота нужно прописать

bot.polling()

ВАЖНО: Весь код который мы будем писать,нужно писать перед активацией бота

Все мы прекрасно занем что в телеграмм ботах есть команды,сейчас мы напишем действие которое у нас будет происходить когда человек напишет команду /start.

Для этого мы воспользуемся декоратором. И создадим метод который он будет вызывать при использовании команды /start.

Для этого мы напишем следующее

@bot.message_handler(commands=['start'])
def start(message):
bot.send_message(message.chat.id,'Привет,я бот для генерации картинок.Для того что бы создать картинку воспользуйся командой /draw "Тут пиши запрос" .Пример запроса: /draw Гиперреалистичный,хомяк с косой,8к')
-11

Что здесь в принципе происходит? Зададутся некоторые вопросом.

@bot.message_handler(commands=['start'])

Это и есть наш декоратор который будет вызывать метод который мы написали.

def start(message):

Это наш метод в который мы передаем переменную message,в данной переменной у нас храниться вся информация о чате то есть Id чата который нам нужен для того что бы бот понимал куда отправлять сообщения, так же здесь храниться сообщение от пользователя.

bot.send_message(message.chat.id,'Привет,я бот для генерации картинок.Для того что бы создать картинку воспользуйся командой /draw "Тут пиши запрос" .' 'Пример запроса: /draw Гиперреалистичный,хомяк с косой,8к')

Данной строчкой мы отправляем сообщение пользователю.

Хорошо теперь перейдем к самой команде /draw (название можете дать сами).

По задумке пользователь должен написать команду /draw и сразу запрос что ему нарисовать. Будем реализовывать)

Так же создаем декоратор и метод.

@bot.message_handler(commands=['draw'])
def draw(message):

Так как для генерации картинки требуется время то мы отправим сообщение для того чтобы человек понимал что бот работает просто требуется время для генерации.

bot.send_message(message.chat.id,"Придется чутка подождать я думаю...")

Далее нам нужно получить запрос на генерацию картинки и перевести его на английский. Для этого мы воспользуемся срезами и библиотекой translate.

mess_text = message.text[6:]
translator = Translator(from_lang="ru", to_lang="en")
text_Eng = translator.translate(mess_text)

Срезаем с 6 символа так как с него у нас и начинается запрос пользователя.

Далее мы создаем json файл в которой мы задаем конфигурацию (не советую ее менять) про конфигурацию можете почитать здесь (https://stablediffusionapi.com/docs/stable-diffusion-api/text2img/),создаем переменную в которой по факту указываем что отправляем post запрос и делаем post запрос на сервер.

payload = json.dumps({
"key": API_AI,
"prompt": text_Eng,
"negative_prompt": None,
"width": "1024",
"height": "1024",
"samples": "1",
"num_inference_steps": "20",
"seed": "99999999",
"guidance_scale": 7.5,
"safety_checker": "yes",
"multi_lingual": "no",
"panorama": "no",
"self_attention": "yes",
"upscale": "no",
"embeddings_model": None,
"webhook": None,
"track_id": None
})

headers = {
'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload)

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

{"status":"success","generationTime":2.8592076301574707,"id":34091146,"output":["https:\/\/cdn2.stablediffusionapi.com\/generations\/68313604-70f3-4b33-a7dd-5fbdf42d5686-0.png"],"meta":{"H":512,"W":512,"enable_attention_slicing":"true","file_prefix":"68313604-70f3-4b33-a7dd-5fbdf42d5686","guidance_scale":7.5,"model":"runwayml\/stable-diffusion-v1-5","n_samples":1,"negative_prompt":"","outdir":"out","prompt":"ultra realistic close up portrait ((beautiful pale cyberpunk female with heavy black eyeliner))","revision":"fp16","safetychecker":"yes","seed":3616476428,"steps":20,"vae":"stabilityai\/sd-vae-ft-mse"}}

Для того чтобы вытянуть от туда ссылку мы воспользуемся хитростью.Мы преобразуем ее в json формат и вытянем ссылку.

Для этого напишем следующее:

json_string = response.text
json_object = json.loads(json_string)
link = json_object["output"][0]

Отлично мы получили ссылку на нашу картинку осталось лишь получить картинку с ссылки и отправить пользователю. Для этого воспользуемся библиотеками request,pillow,IO. Мы получим битовую последовательность с ссылки и преобразуем ее в картинку,а уже потом отправим пользователю.

response = requests.get(link)

byte_io = io.BytesIO(response.content)

image = Image.open(byte_io)

image_byte_io = io.BytesIO()

image.save(image_byte_io, format='PNG')

image_byte_io.seek(0)

bot.send_photo(message.chat.id, image)

Отлично,по факту наш бот готов,вот полный код для команды draw

@bot.message_handler(commands=['draw'])
def draw(message):
bot.send_message(message.chat.id,"Прийдеться чутка подождать я думаю...")
mess_text = message.text[6:]
print(mess_text)
translator = Translator(from_lang="ru", to_lang="en")
text_Eng = translator.translate(mess_text)
print(text_Eng)
payload = json.dumps({
"key": AI,
"prompt": text_Eng,
"negative_prompt": None,
"width": "1024",
"height": "1024",
"samples": "1",
"num_inference_steps": "20",
"seed": "99999999",
"guidance_scale": 7.5,
"safety_checker": "yes",
"multi_lingual": "no",
"panorama": "no",
"self_attention": "yes",
"upscale": "no",
"embeddings_model": None,
"webhook": None,
"track_id": None
})

headers = {
'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload)
json_string = response.text
print(json_string)
json_object = json.loads(json_string)

link = json_object["output"][0]

response = requests.get(link)

byte_io = io.BytesIO(response.content)

image = Image.open(byte_io)

image_byte_io = io.BytesIO()

image.save(image_byte_io, format='PNG')

image_byte_io.seek(0)

bot.send_photo(message.chat.id, image)

Главное учтите что у сервиса всего 20 бесплатных запросов,но если хотите еще побаловаться с ботом просто создайте новый аккаунт.

Спасибо за внимание!