import asyncio import os from io import BytesIO from PIL import Image, ImageDraw, ImageFilter, ImageOps from pyrogram import Client, filters, enums from pyrogram.types import Message # noinspection PyUnresolvedReferences from utils.misc import modules_help, prefix # noinspection PyUnresolvedReferences from utils.scripts import import_library, format_exc 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.", }