Загрузка...

Ready-made bot for adding text to photos via tg bot

Thread in Python created by anrlfdl Jan 10, 2025. 245 views

  1. anrlfdl
    anrlfdl Topic starter Jan 10, 2025 4 Nov 27, 2023
    Данный бот добавляет текст на изображения из локальной папки на машине и отправляет пользователю, так же есть отстук в телеграмм админу о совершенных действиях других юзеров.​

    Python
    import logging
    import os
    from telegram import Update, InputFile, ReplyKeyboardMarkup, ReplyKeyboardRemove
    from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, ContextTypes, filters
    from PIL import Image, ImageDraw, ImageFont

    # Настройка логирования
    logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    level=logging.INFO,
    )

    # Директории
    IMAGE_DIR = "путь до папки с изображениями на которые будет добавляться текст"
    OUTPUT_DIR = "путь до папки с выходными изображениями"
    FONT_DIR = "путь к папке с используемыми шрифтами"

    os.makedirs(IMAGE_DIR, exist_ok=True)
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    os.makedirs(FONT_DIR, exist_ok=True)

    # Конфигурация изображений
    IMAGE_CONFIG = {
    "черно-белый логотип.png": {
    "rotation_angle": 0,
    "text1": {"x": 92, "y": 287, "font_size": 27, "color": "black", "font": "Myriad Pro Bold.ttf"},
    "text2": {"x": 92, "y": 303, "font_size": 45, "color": "black", "font": "Myriad Pro Bold.ttf"},
    },
    "розовый логотип.png": {
    "rotation_angle": 0,
    "text1": {"x": 92, "y": 287, "font_size": 27, "color": "black", "font": "Myriad Pro Bold.ttf"},
    "text2": {"x": 92, "y": 303, "font_size": 45, "color": "black", "font": "Myriad Pro Bold.ttf"},
    },
    "цветной поворотный.png": {
    "rotation_angle": 90,
    "text1": {"x": 540, "y": 440, "font_size": 41, "color": "black", "font": "Arial Narrow Bold.ttf"},
    "text2": {"x": 700, "y": 430, "font_size": 50, "color": "black", "font": "Arial Narrow Bold.ttf"},
    },
    }

    SUPPORTED_FORMATS = (".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff")

    # Хранение состояния пользователя
    USER_STATE = {}

    # Список администраторов
    ADMINS = [999999] # Замените на реальные ID администраторов

    # Функция отправки уведомлений администраторам
    async def notify_admins(context: ContextTypes.DEFAULT_TYPE, message: str) -> None:
    for admin_id in ADMINS:
    try:
    await context.bot.send_message(chat_id=admin_id, text=message)
    except Exception as e:
    logging.error(f"Не удалось отправить сообщение админу {admin_id}: {e}")

    # Команда /start
    async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    USER_STATE.pop(update.message.from_user.id, None) # Сброс состояния пользователя

    keyboard = [["Выбрать изображение"]]
    reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True)

    await update.message.reply_text(
    "Привет! Я бот для добавления текста на изображения. Нажмите 'Выбрать изображение', чтобы начать.",
    reply_markup=reply_markup,
    )

    # Уведомление админам
    await notify_admins(context, f"Пользователь {update.message.from_user.username} ({update.message.from_user.id}) начал сессию.")

    # Обработка выбора изображения
    async def choose_image(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.message.from_user.id
    files = [f for f in os.listdir(IMAGE_DIR) if f.lower().endswith(SUPPORTED_FORMATS)]

    if not files:
    await update.message.reply_text("Нет доступных изображений в поддерживаемых форматах.", reply_markup=ReplyKeyboardRemove())
    return

    USER_STATE[user_id] = {"step": "choose_file"}

    keyboard = [[file] for file in files]
    reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True, one_time_keyboard=True)

    await update.message.reply_text("Выберите изображение из списка:", reply_markup=reply_markup)

    # Уведомление админам
    await notify_admins(context, f"Пользователь {update.message.from_user.username} ({update.message.from_user.id}) выбирает изображение.")

    # Обработка выбора файла
    async def handle_file_selection(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.message.from_user.id
    state = USER_STATE.get(user_id, {})

    if state.get("step") != "choose_file":
    return

    file_name = update.message.text

    if not os.path.exists(os.path.join(IMAGE_DIR, file_name)):
    await update.message.reply_text("Файл не найден. Попробуйте снова.")
    return

    USER_STATE[user_id]["file_name"] = file_name
    USER_STATE[user_id]["step"] = "text1"

    await update.message.reply_text("Введите первый текст:", reply_markup=ReplyKeyboardRemove())

    # Уведомление админам
    await notify_admins(context, f"Пользователь {update.message.from_user.username} ({update.message.from_user.id}) выбрал файл: {file_name}")

    # Обработка ввода текста
    async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.message.from_user.id
    state = USER_STATE.get(user_id, {})

    if not state:
    return

    if state.get("step") == "text1":
    USER_STATE[user_id]["text1"] = update.message.text
    USER_STATE[user_id]["step"] = "text2"
    await update.message.reply_text("Введите второй текст:")

    # Уведомление админам
    await notify_admins(context, f"Пользователь {update.message.from_user.username} ({update.message.from_user.id}) ввел первый текст: {update.message.text}")

    elif state.get("step") == "text2":
    USER_STATE[user_id]["text2"] = update.message.text
    await process_image(update, context)

    # Уведомление админам
    await notify_admins(context, f"Пользователь {update.message.from_user.username} ({update.message.from_user.id}) ввел второй текст: {update.message.text}")

    # Обработка изображения
    async def process_image(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.message.from_user.id
    state = USER_STATE.get(user_id, {})

    file_name = state.get("file_name")
    text1 = state.get("text1")
    text2 = state.get("text2")

    if not file_name or not text1 or not text2:
    await update.message.reply_text("Ошибка состояния. Попробуйте начать сначала с команды /start.")
    return

    image_path = os.path.join(IMAGE_DIR, file_name)
    config = IMAGE_CONFIG.get(file_name)
    if not config:
    await update.message.reply_text("Конфигурация для изображения не найдена.")
    return

    try:
    # Открываем изображение
    image = Image.open(image_path)

    # Рисуем текст 1
    font1 = ImageFont.truetype(os.path.join(FONT_DIR, config["text1"]["font"]), config["text1"]["font_size"])
    draw = ImageDraw.Draw(image)
    draw.text((config["text1"]["x"], config["text1"]["y"]), text1, fill=config["text1"]["color"], font=font1)

    # Рисуем текст 2
    font2 = ImageFont.truetype(os.path.join(FONT_DIR, config["text2"]["font"]), config["text2"]["font_size"])
    draw.text((config["text2"]["x"], config["text2"]["y"]), text2, fill=config["text2"]["color"], font=font2)

    # Поворот готового изображения
    rotation_angle = config.get("rotation_angle", 0)
    if rotation_angle != 0:
    image = image.rotate(rotation_angle, expand=True)

    # Сохранение результата
    output_path = os.path.join(OUTPUT_DIR, f"processed_{file_name}")
    image.save(output_path)

    # Отправляем результат пользователю
    with open(output_path, "rb") as file:
    await update.message.reply_photo(photo=InputFile(file), caption="Изображение успешно обработано!")

    # Уведомление админам
    await notify_admins(context, f"Пользователь {update.message.from_user.username} ({update.message.from_user.id}) обработал изображение: {file_name}")

    except Exception as e:
    logging.error(f"Ошибка: {e}")
    await update.message.reply_text("Произошла ошибка при обработке изображения.")
    finally:
    USER_STATE.pop(user_id, None)
    await update.message.reply_text("Процесс завершен. Нажмите /start, чтобы начать заново.")

    # Главная функция запуска бота
    def main():
    token = "" # Вставьте свой токен

    app = ApplicationBuilder().token(token).build()

    app.add_handler(CommandHandler("start", start))
    app.add_handler(MessageHandler(filters.Regex("^(Выбрать изображение)$"), choose_image))
    app.add_handler(MessageHandler(filters.Regex(r"^.+\.(jpg|jpeg|png|bmp|gif|tiff)$"), handle_file_selection))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text))

    print("Бот запущен. Нажмите Ctrl+C для остановки.")
    app.run_polling()


    if __name__ == "__main__":
    main()
    1.замените параметр 193 строчки token = "" на токен своего бота
    2.замените параметр ADMINS = [999999] на реальные для правильной работы отстука о действиях юзеров
    3. отредактируйте пути к файлам
    IMAGE_DIR = "путь до папки с изображениями на которые будет добавляться текст"
    OUTPUT_DIR = "путь до папки с выходными изображениями"
    FONT_DIR = "путь к папке с используемыми шрифтами"
    4.в части IMAGE_CONFIG замените имена файлов на те, что будут использоваться
    pip install python-telegram-bot==20.3
    pip install Pillow==10.0.0
    "rotation_angle": 0, - угол поворота изображения ПОСЛЕ нанесения текста
    "x": 540 - координата текста на изображении по оси Х
    "y": 540 - координата текста на изображении по оси Y
    "font_size": 41 - размер текста
    "color": "black" - цвет текста
    "font": "Myriad Pro Bold.ttf" - шрифт текста, берущийся из папки которую мы указывали выше
     
  2. derkown
    великолепно!
     
    1. морфий
      derkown, сногсшибательно нахуй!
  3. Getrequest
    Getrequest Jan 11, 2025 Чекер почт 65к доменов - lolz.live/threads/7313296
    5 строк твоих и 202 от ии :+rep:
     
Top
Loading...