import asyncio import os from io import BytesIO from PIL import Image, ImageDraw, ImageFilter, ImageOps from pyrogram import Client, enums, filters from pyrogram.types import Message # noinspection PyUnresolvedReferences from utils.misc import modules_help, prefix # noinspection PyUnresolvedReferences from utils.scripts import format_exc, import_library VideoFileClip = import_library('moviepy', 'moviepy==2.2.1').VideoFileClip im = None def process_img(filename): global im im = Image.open(f'downloads/{filename}') w, h = im.size img = Image.new('RGBA', (w, h), (0, 0, 0, 0)) img.paste(im, (0, 0)) m = min(w, h) img = img.crop(((w - m) // 2, (h - m) // 2, (w + m) // 2, (h + m) // 2)) w, h = img.size mask = Image.new('L', (w, h), 0) draw = ImageDraw.Draw(mask) draw.ellipse((10, 10, w - 10, h - 10), fill=255) mask = mask.filter(ImageFilter.GaussianBlur(2)) img = ImageOps.fit(img, (w, h)) img.putalpha(mask) im = BytesIO() im.name = 'img.webp' img.save(im) im.seek(0) video = None def process_vid(filename): global video video = VideoFileClip(f'downloads/{filename}') w, h = video.size m = min(w, h) box = { 'x1': (w - m) // 2, 'y1': (h - m) // 2, 'x2': (w + m) // 2, 'y2': (h + m) // 2, } video = video.cropped(**box) @Client.on_message(filters.command(['circle', 'round'], prefix) & filters.me) async def circle(_, message: Message): try: if not message.reply_to_message: return await message.reply( 'Reply is required for this command', parse_mode=enums.ParseMode.HTML, ) if message.reply_to_message.photo: filename = 'circle.jpg' typ = 'photo' elif message.reply_to_message.sticker: if message.reply_to_message.sticker.is_video: return await message.reply( 'Video stickers is not supported', parse_mode=enums.ParseMode.HTML, ) filename = 'circle.webp' typ = 'photo' elif message.reply_to_message.video: filename = 'circle.mp4' typ = 'video' elif message.reply_to_message.document: _filename = message.reply_to_message.document.file_name.casefold() if _filename.endswith('.png'): filename = 'circle.png' typ = 'photo' elif _filename.endswith('.jpg'): filename = 'circle.jpg' typ = 'photo' elif _filename.endswith('.jpeg'): filename = 'circle.jpeg' typ = 'photo' elif _filename.endswith('.webp'): filename = 'circle.webp' typ = 'photo' elif _filename.endswith('.mp4'): filename = 'circle.mp4' typ = 'video' else: return await message.reply('Invalid file type', parse_mode=enums.ParseMode.HTML) else: return await message.reply('Invalid file type', parse_mode=enums.ParseMode.HTML) if typ == 'photo': await message.edit('Processing image📷', parse_mode=enums.ParseMode.HTML) await message.reply_to_message.download(f'downloads/{filename}') await asyncio.get_event_loop().run_in_executor(None, process_img, filename) await message.delete() return await message.reply_sticker(sticker=im, reply_to_message_id=message.reply_to_message.id) else: await message.edit('Processing video🎥', parse_mode=enums.ParseMode.HTML) await message.reply_to_message.download(f'downloads/{filename}') await asyncio.get_event_loop().run_in_executor(None, process_vid, filename) await message.edit('Saving video📼', parse_mode=enums.ParseMode.HTML) await asyncio.get_event_loop().run_in_executor(None, video.write_videofile, 'downloads/result.mp4') await message.delete() await message.reply_video_note( video_note='downloads/result.mp4', duration=int(video.duration), reply_to_message_id=message.reply_to_message.id, ) if isinstance(video, VideoFileClip): video.close() os.remove(f'downloads/{filename}') os.remove('downloads/result.mp4') except Exception as e: await message.reply(format_exc(e), parse_mode=enums.ParseMode.HTML) modules_help['circle'] = { 'round': 'Round a photo or video.', 'circle': 'Circle a photo or video.', }