├── .gitignore ├── README.md ├── bot.py ├── LICENSE └── emojify.py /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | 3 | **/__pycache__ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # emojify-bot 2 | ![image](https://user-images.githubusercontent.com/61446939/148486314-c5370d66-365e-4c79-a0d1-69d20298bbb9.png) 3 | -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Union 3 | import discord 4 | from dotenv import load_dotenv 5 | from PIL import Image 6 | from discord.ext import commands 7 | from emojify import emojify_image 8 | import requests # It's not blocking, you can use aiohttp if you want 9 | 10 | bot = commands.Bot(command_prefix="e>") 11 | 12 | 13 | @bot.command() 14 | async def emojify(ctx, url: Union[discord.Member, str], size: int = 14): 15 | if not isinstance(url, str): 16 | url = url.display_avatar.url 17 | 18 | def get_emojified_image(): 19 | r = requests.get(url, stream=True) 20 | image = Image.open(r.raw).convert("RGB") 21 | res = emojify_image(image, size) 22 | 23 | if size > 14: 24 | res = f"```{res}```" 25 | return res 26 | 27 | result = await bot.loop.run_in_executor(None, get_emojified_image) 28 | await ctx.send(result) 29 | 30 | 31 | load_dotenv() 32 | bot.run(os.environ["TOKEN"]) 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Swas.py 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /emojify.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | 3 | # Real colors don't work as well I guess 4 | # COLORS = { 5 | # (49, 55, 61): "⬛", 6 | # (85, 172, 238): "🟦", 7 | # (221, 46, 68): "🟥", 8 | # (253, 203, 88): "🟨", 9 | # (193, 105, 79): "🟫", 10 | # (244, 144, 12): "🟧", 11 | # (170, 142, 214): "🟪", 12 | # (230, 231, 232): "⬜", 13 | # (120, 177, 89): "🟩", 14 | # } 15 | 16 | # These colors work a bit better maybe 17 | COLORS = { 18 | (0, 0, 0): "⬛", 19 | (0, 0, 255): "🟦", 20 | (255, 0, 0): "🟥", 21 | (255, 255, 0): "🟨", 22 | # (190, 100, 80): "🟫", 23 | (255, 165, 0): "🟧", 24 | # (160, 140, 210): "🟪", 25 | (255, 255, 255): "⬜", 26 | (0, 255, 0): "🟩", 27 | } 28 | 29 | 30 | def euclidean_distance(c1, c2): 31 | r1, g1, b1 = c1 32 | r2, g2, b2 = c2 33 | d = ((r2 - r1) ** 2 + (g2 - g1) ** 2 + (b2 - b1) ** 2) ** 0.5 34 | 35 | return d 36 | 37 | 38 | def find_closest_emoji(color): 39 | c = sorted(list(COLORS), key=lambda k: euclidean_distance(color, k)) 40 | return COLORS[c[0]] 41 | 42 | 43 | def emojify_image(img, size=14): 44 | 45 | WIDTH, HEIGHT = (size, size) 46 | small_img = img.resize((WIDTH, HEIGHT), Image.NEAREST) 47 | 48 | emoji = "" 49 | small_img = small_img.load() 50 | for y in range(HEIGHT): 51 | for x in range(WIDTH): 52 | emoji += find_closest_emoji(small_img[x, y]) 53 | emoji += "\n" 54 | return emoji 55 | --------------------------------------------------------------------------------