Наложение водяного знака в PIL

Рейтинг: 0Ответов: 1Опубликовано: 26.04.2023

Имеется бот: задача бота: Пользователь отправляет первую фотографию на которую хочет наложить водяной знак. Далее отправляет второе изображение самого водяного знака. И далее бот отправляет пользователю первое фото с наложенным поверх водяным знаком (фото от пользователя номер два)

Первая картинка:

Далее загружаю изображение номер два(Водяной знак)

введите сюда описание изображения

На выходе получается вот такое изображение

введите сюда описание изображения

ЖЕЛАЕМЫЙ РЕЗУЛЬТАТ НА ВЫХОДЕ

введите сюда описание изображения

Код снизу, какие параметры изменить и как это можно реализовать?

@dp.message_handler(content_types=['photo'], state=Groupuser.znak)
async def load_znak(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['znak'] = message.photo[2].file_id #Выбираем самое высокое разрешение

    photo = requests.get(URI_INFO + data['photo']) #Отправляем гет запрос и получае данные о фото
    photo_path = photo.json()['result']['file_path'] #Получаем путь файла
    photo_content = requests.get(URI + photo_path) #Отправляем гет запрос и получаем фото
    user_photo = Image.open(io.BytesIO(photo_content.content)).convert('RGBA') #Отправляем фото в буфер в байтах. Конвертируем в RGBA


    photo_z = requests.get(URI_INFO + data['znak'])
    photo_path_z = photo_z.json()['result']['file_path']
    photo_content_z = requests.get(URI + photo_path_z)
    user_photo_z = Image.open(io.BytesIO(photo_content_z.content)).resize((400,100)).convert('RGBA') #Указали размер водяного изображения
    user_photo_z.putalpha(100) #Указали прозрачность


    #Вставляем водяной знак
    width, height = user_photo.size #Берем размер первого фото
    transparent = Image.new('RGBA', (width, height), (0, 0, 0, 0)) #Создаем новое изображение и указываем размер, координаты
    transparent.paste(user_photo, (0, 0)) #Вставляем наше первое фото, позиция 0,0
    position = 50, 200 #Позиция для водяного знака

    transparent.paste(user_photo_z, position, mask=user_photo_z) #Вставляем наш водяной знак и указываем прозрачность

    transparent.save('Watemark.png', format='png') #Сохраняем наш итоговый результат
    photo_send = open('Watemark.png', 'rb') #Открываем наш результат
    await bot.send_photo(chat_id=message.chat.id, photo=photo_send)
    os.remove('C:\тг бот тест\photo\Watemark.png')
    await state.finish()

Ответы

▲ 0

Вот функция для добавления watermark на изображение:

from PIL import Image
import numpy as np


def add_watermark(main_image: Image.Image, watermark: Image.Image, position: tuple) -> Image.Image:
    res = main_image.copy().convert('RGBA')
    watermark = watermark.convert('RGBA')

    x = np.asarray(watermark).copy()
    x[:, :, 3] = (100 * (np.sum(x[:, :, :3], axis=2) < 700)).astype(np.uint8)
    watermark = Image.fromarray(x)

    alpha = watermark.getchannel('A')
    crop = alpha.getbbox()
    watermark = watermark.crop(crop)

    res.alpha_composite(watermark, position)

    return res

Использование в вашем коде:

@dp.message_handler(content_types=['photo'], state=Groupuser.znak)
async def load_znak(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['znak'] = message.photo[2].file_id #Выбираем самое высокое разрешение

    photo = requests.get(URI_INFO + data['photo']) #Отправляем гет запрос и получае данные о фото
    photo_path = photo.json()['result']['file_path'] #Получаем путь файла
    photo_content = requests.get(URI + photo_path) #Отправляем гет запрос и получаем фото
    user_photo = Image.open(io.BytesIO(photo_content.content))


    photo_z = requests.get(URI_INFO + data['znak'])
    photo_path_z = photo_z.json()['result']['file_path']
    photo_content_z = requests.get(URI + photo_path_z)
    user_photo_z = Image.open(io.BytesIO(photo_content_z.content))

    position = 50, 200  # Позиция для водяного знака

    add_watermark(user_photo, user_photo_z, position).save('Watemark.png', format='png') #Сохраняем наш итоговый результат
    photo_send = open('Watemark.png', 'rb') #Открываем наш результат
    await bot.send_photo(chat_id=message.chat.id, photo=photo_send)
    os.remove('C:\тг бот тест\photo\Watemark.png')
    await state.finish()