Всем привет,недавно появилась идея написать бота в телеграмме для генерации изображения,но никак не мог найти материалов для этого,покопавшись наткнулся на проект Stable Diffusion.
Данный проект имеет открытый код. Что как раз нам и нужно для написания бота для генерации изображения.
Первое что нам понадобиться для создания нашего проекта это API ключ с Stable Diffusion и API ключ для будущего телеграмм бота.
1.Получим ключ Stable Diffusion.
Для этого перейдем по ссылке https://stablediffusionapi.com/ и зарегистрируемся на проекте.
После прохождения регистрации нужно на жать на кнопку API settings,она находиться на верхней панели.
После мы попадаем в настройки API ключа.Для получения нашего API ключа ну жно нажать на боковой панели на API keys.
Здесь нужно дать название нашему API ключу и нажать на кнопку Create new key.
После этого нажимаем на кнопку View API Keys и копируем его.
Теперь перейдем в Pycharm и создадим новый файл с названием 'config',в даном файле у нас будет всего две переменные для хранения наших API ключей это делается для того чтобы они не хранились прямо в коде.
Далее создаем переменную API_AI и вставляем туда наш ключ от ИИ.
Отлично,теперь перейдем в телеграмм бота Bot_father и создадим там нашего бота.Для удобства держите ссылочку на бота @BotFather.
Пишем боту команду /newbot и следуем инструкциям в конце получаем сообщение с API ключом от нашего бота.
Ключ выглядит примерно так 6339942231:AAHl8Ld33SYzUcH8w0Jm4Yzb9Z25HrFXaow
*Не беспокойтесь я дал старый не рабочий API ключ*
Далее снова переходим в Pycharm и в файле config создаем вторую переменную API_bot в которую так же вставляем полученный нами ключ.
Все отлично подготовку мы сделали перейдем к созданию самого бота.
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
После установки импортируем их в наш проект
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
Вот так должны выглядеть все наши импортированные библиотеки
Далее создадим переменную в которой у нас будет храниться ссылка на которую мы будем отправлять Post запрос для генерации изображения,и создадим переменную которая будет отвечать за действия бота.
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к')
Что здесь в принципе происходит? Зададутся некоторые вопросом.
@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 бесплатных запросов,но если хотите еще побаловаться с ботом просто создайте новый аккаунт.
Спасибо за внимание!