mirror of
https://github.com/MuRuLOSE/limoka.git
synced 2026-06-17 14:54:18 +02:00
Commited backup
This commit is contained in:
245
GeekTG/FTG-Modules/image_editor.py
Normal file
245
GeekTG/FTG-Modules/image_editor.py
Normal file
@@ -0,0 +1,245 @@
|
||||
"""
|
||||
.------.------.------.------.------.------.------.------.------.------.
|
||||
|D.--. |4.--. |N.--. |1.--. |3.--. |L.--. |3.--. |K.--. |0.--. |0.--. |
|
||||
| :/\: | :/\: | :(): | :/\: | :(): | :/\: | :(): | :/\: | :/\: | :/\: |
|
||||
| (__) | :\/: | ()() | (__) | ()() | (__) | ()() | :\/: | :\/: | :\/: |
|
||||
| '--'D| '--'4| '--'N| '--'1| '--'3| '--'L| '--'3| '--'K| '--'0| '--'0|
|
||||
`------`------`------`------`------`------`------`------`------`------'
|
||||
|
||||
Copyright 2022 t.me/D4n13l3k00
|
||||
Licensed under the Creative Commons CC BY-NC-ND 4.0
|
||||
|
||||
Full license text can be found at:
|
||||
https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode
|
||||
|
||||
Human-friendly one:
|
||||
https://creativecommons.org/licenses/by-nc-nd/4.0
|
||||
"""
|
||||
# meta developer: @D4n13l3k00
|
||||
|
||||
|
||||
# requires: Pillow aiohttp fake-useragent
|
||||
|
||||
import hashlib
|
||||
import io
|
||||
import re
|
||||
from datetime import date
|
||||
|
||||
import aiohttp
|
||||
from fake_useragent import UserAgent
|
||||
from PIL import Image, ImageEnhance, ImageOps
|
||||
from telethon import types
|
||||
|
||||
from .. import loader, utils
|
||||
|
||||
|
||||
@loader.tds
|
||||
class ImageEditorMod(loader.Module):
|
||||
"ImageEditor - Simple tool for working with images"
|
||||
strings = {
|
||||
"name": "ImageEditor",
|
||||
"downloading": "<b>[{}]</b> Downloading...",
|
||||
"working": "<b>[{}]</b> Working...",
|
||||
"exporting": "<b>[{}]</b> Exporting...",
|
||||
"set_value": "<b>[{}]</b> Specify the level...",
|
||||
"set_size": "<b>[{}]</b> Specify the size...",
|
||||
"reply": "<b>[{}]</b> reply to image...",
|
||||
"set_time": "<b>[{}]</b> Specify the time in the format start(ms):end(ms)",
|
||||
}
|
||||
|
||||
@loader.owner
|
||||
async def resizeicmd(self, m: types.Message):
|
||||
".resizei <w> <h> - Resize image"
|
||||
_pref = "Resize"
|
||||
args = utils.get_args_raw(m)
|
||||
r = re.compile(r"^(\d+)\s+(\d+)$")
|
||||
if not args or not r.match(args):
|
||||
return await utils.answer(m, self.strings("set_size", m).format(_pref))
|
||||
w, h = [int(i) for i in r.match(args).groups()]
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
out = im.image.resize((w, h))
|
||||
await go_out(self, m, im, out, _pref)
|
||||
|
||||
@loader.owner
|
||||
async def rmbgicmd(self, m: types.Message):
|
||||
".rmbgi - Remove background via AI [Powered by Indian's AI]"
|
||||
_pref = "RemoveBg"
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
b = io.BytesIO()
|
||||
b.name = "i.png"
|
||||
im.image.save(b, "PNG")
|
||||
b.seek(0)
|
||||
out = None
|
||||
async with aiohttp.ClientSession(
|
||||
headers={"User-Agent": UserAgent().chrome}
|
||||
) as s:
|
||||
form = aiohttp.FormData()
|
||||
form.add_field("file", b)
|
||||
form.add_field("filenameOverride", "true")
|
||||
form.add_field(
|
||||
"path",
|
||||
f"__editor/{date.year}-{date.month}-{date.day}/{hashlib.md5(b.read()).hexdigest()}",
|
||||
)
|
||||
b.seek(0)
|
||||
async with s.post(
|
||||
"https://api.erase.bg/service/panel/assets/v1.0/upload/direct",
|
||||
data=form,
|
||||
) as r:
|
||||
_url = (await r.json())["url"]
|
||||
async with s.get(
|
||||
_url.replace("dummy-cloudname/original", "dummy-cloudname/erase.bg()")
|
||||
) as r:
|
||||
i = io.BytesIO(await r.read())
|
||||
i.name = "ImageEditor.jpeg"
|
||||
out = Image.open(i)
|
||||
await go_out(self, m, im, out, _pref, True)
|
||||
|
||||
@loader.owner
|
||||
async def inverticmd(self, m: types.Message):
|
||||
".inverti - Invert colors"
|
||||
_pref = "Invert"
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
out = ImageOps.invert(im.image)
|
||||
await go_out(self, m, im, out, _pref)
|
||||
|
||||
@loader.owner
|
||||
async def bwicmd(self, m: types.Message):
|
||||
".bwi - BlackWhite"
|
||||
_pref = "BlackWhite"
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
out = im.image.convert("L")
|
||||
await go_out(self, m, im, out, _pref)
|
||||
|
||||
@loader.owner
|
||||
async def convicmd(self, m: types.Message):
|
||||
".convi - Sticker to image | Image to sticker"
|
||||
_pref = "Converter"
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
im.is_webp = not im.is_webp
|
||||
await go_out(self, m, im, im.image, _pref)
|
||||
|
||||
@loader.owner
|
||||
async def rotateicmd(self, m: types.Message):
|
||||
".rotatei <degrees> - Rotate image"
|
||||
_pref = "Rotate"
|
||||
args = utils.get_args_raw(m)
|
||||
r = re.compile(r"^(\d+)$")
|
||||
if not args or not r.match(args):
|
||||
return await utils.answer(m, self.strings("set_value", m).format(_pref))
|
||||
degrees = int(r.match(args).groups()[0])
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
out = im.image.rotate(degrees, expand=True)
|
||||
await go_out(self, m, im, out, _pref)
|
||||
|
||||
@loader.owner
|
||||
async def contrasticmd(self, m: types.Message):
|
||||
".contrasti <float> - Change contrast"
|
||||
_pref = "Contrast"
|
||||
args = utils.get_args_raw(m)
|
||||
r = re.compile(r"^(\d*\.?\d*)$")
|
||||
if not args or not r.match(args):
|
||||
return await utils.answer(m, self.strings("set_value", m).format(_pref))
|
||||
level = float(r.match(args).groups()[0])
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
out = ImageEnhance.Contrast(im.image).enhance(level)
|
||||
await go_out(self, m, im, out, _pref)
|
||||
|
||||
@loader.owner
|
||||
async def sharpnessicmd(self, m: types.Message):
|
||||
".sharpnessi <float> - Change sharpness"
|
||||
_pref = "Sharpness"
|
||||
args = utils.get_args_raw(m)
|
||||
r = re.compile(r"^(\d*\.?\d*)$")
|
||||
if not args or not r.match(args):
|
||||
return await utils.answer(m, self.strings("set_value", m).format(_pref))
|
||||
level = float(r.match(args).groups()[0])
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
out = ImageEnhance.Sharpness(im.image).enhance(level)
|
||||
await go_out(self, m, im, out, _pref)
|
||||
|
||||
@loader.owner
|
||||
async def brighticmd(self, m: types.Message):
|
||||
".brighti <float> - Change bright"
|
||||
_pref = "Color"
|
||||
args = utils.get_args_raw(m)
|
||||
r = re.compile(r"^(\d*\.?\d*)$")
|
||||
if not args or not r.match(args):
|
||||
return await utils.answer(m, self.strings("set_value", m).format(_pref))
|
||||
level = float(r.match(args).groups()[0])
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
out = ImageEnhance.Brightness(im.image).enhance(level)
|
||||
await go_out(self, m, im, out, _pref)
|
||||
|
||||
@loader.owner
|
||||
async def coloricmd(self, m: types.Message):
|
||||
".colori <float> - Change color factor"
|
||||
_pref = "Color"
|
||||
args = utils.get_args_raw(m)
|
||||
r = re.compile(r"^(\d*\.?\d*)$")
|
||||
if not args or not r.match(args):
|
||||
return await utils.answer(m, self.strings("set_value", m).format(_pref))
|
||||
level = float(r.match(args).groups()[0])
|
||||
im = await get_image(self, m, _pref)
|
||||
if not im:
|
||||
return
|
||||
out = ImageEnhance.Color(im.image).enhance(level)
|
||||
await go_out(self, m, im, out, _pref)
|
||||
|
||||
|
||||
class ImageEditorClass:
|
||||
image: Image.Image = None
|
||||
message = None
|
||||
is_webp: bool = None
|
||||
pref: str = None
|
||||
reply = None
|
||||
|
||||
|
||||
async def get_image(self, m, pref: str) -> ImageEditorClass:
|
||||
r = await m.get_reply_message()
|
||||
if r and r.file and r.file.mime_type.split("/")[0] in ["image"]:
|
||||
im = ImageEditorClass()
|
||||
im.pref = pref
|
||||
im.reply = r
|
||||
im.is_webp = r.file.ext == ".webp"
|
||||
m = await utils.answer(m, self.strings("downloading", m).format(pref))
|
||||
im.image = Image.open(io.BytesIO(await r.download_media(bytes)))
|
||||
im.message = await utils.answer(m, self.strings("working", m).format(pref))
|
||||
return im
|
||||
await utils.answer(m, self.strings("reply", m).format(pref))
|
||||
|
||||
|
||||
async def go_out(
|
||||
self, m, im: ImageEditorClass, out: Image.Image, pref, force_document=False
|
||||
):
|
||||
m = await utils.answer(m, self.strings("exporting", m).format(pref))
|
||||
iba = io.BytesIO()
|
||||
if im.is_webp:
|
||||
out.thumbnail((512, 512))
|
||||
out.save(iba, format="WEBP" if im.is_webp else "PNG")
|
||||
iba.name = "ImageEditor." + ("webp" if im.is_webp else "png")
|
||||
iba.seek(0)
|
||||
await utils.answer(
|
||||
m,
|
||||
iba,
|
||||
reply_to=im.reply.id,
|
||||
supports_streaming=True,
|
||||
force_document=force_document if not im.is_webp else False,
|
||||
)
|
||||
Reference in New Issue
Block a user