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.",
}