博客:https://www.mintimate.cn Mintimate’s Blog,只为与你分享
新年快乐嗷。给大家分享一下Emoji合成,助力欢乐加倍!让我们看看两个Emoji表情,可以合成出什么新表情,丰富聊天内容,让对话更加有趣!
Emoji Kitchen 是由 Google 键盘 Gboard 推出的功能。它允许用户将两个不同的 emoji 进行组合,创造出独特的表情符号。
用户可以在 Google 搜索中输入 Emoji Kitchen 来使用这个功能。生成的新表情以图片的形式呈现,用户可以方便地复制并粘贴到他们的聊天应用程序或社交媒体中。
可能相比一些工具,两个Emoji合成出新的EmojiMix,似乎并没有什么作用;但是就和表情包一样,单论本身,说起来是没有意义,但是却实打实地丰富了聊天内容,让对话更加有趣。
Emoji Kitchen 可以在Google的搜索引擎上搜索Emoji Kitchen
,即可体验Emoji的合成:
我们可以选定两个Emoji,合成出新的Emoji:
它是如何做到图片合成的呢? 是现在很火的AIGC,由AI对两个Emoji进行合成么?
其实并不是,早在2019年底,就有Emoji Kitchen,那个时候,GPT-2刚刚发布,可以生成自然语言文本,但质量和多样性有限,远远不及现在的GPT3.5,更不用说是可以处理图片的AI了。
当然,不排除Google有算法,在2018年时候就使用图形处理,实现合成Emoji的AI;但是这种可能性很低,大概率还是设计师设计制作。
不过,在搜索引擎上使用,有一些不优雅,容易被其他搜索结果所干扰;更重要的是,中国大陆用户无法访问,我们可以试试第三方复刻版本的Emoji Mix。
部分东西,还是视频比较清晰。
这里做个视频,主要内容:
可以访问一下网站进行配套视频的查看:
其实有非常多的Emoji Kitchen复刻版本,为了区别于Google官方的Emoji Kitchen,这里我们粗略地都称作:Emoji Mix。一般Emoji Mix都是使用Emoji Kitchen的图片源…… 我使用Python爬取了Google Emoji Kitchen,发现累计到现在,大概有5w张图片,占用空间500MB,估计很多网站都不会专门存储……
比较常见的Emoji Mix有很多,我们枚举一些。
哈哈,首先当然是我复刻的版本:
效果图如下:
左侧进行Emoji的合成检录,右侧Emoji进行结果的筛选。点击中间的结果区可以进行合成后的Emoji下载:
还有什么惊喜呢? 大家可以自己探索一下。
接下来的选手,相信大家也非常熟悉了:
效果图如下:
EmojiMix Tikolu也是非常好用的Emoji Mix版本;点击左侧的搜索🔍按钮,可以进行检录:
不过,或许是为了适配动态Webp原因。EmojiMix Tikolu只选取了含有动态Webp的Emoji进行展示和参与合成,没有动态Webp的就不进行展示和参与合成了。举个动态Webp的例子:https://fonts.gstatic.com/s/e/notoemoji/latest/1f62f/512.webp
说实话,我一开始并没有接触Google的Emoji Kitchen,就是小伙伴发EmojiMix Tikolu的链接🔗给我,我玩了大半个下午…… 甚至,后来选择一张Emoji合成图片,作为自己的头像(后来觉得太阳光了,还是应该深沉一些就换掉了)。
最后介绍一个重磅选手,实际上官方项目名字叫Emoji-kitchen,但是我为了和Google进行区分,并且它是使用React进行技术实现的,所以我这里就给它取个别名啦:
和上文一样,我们看看效果:
是不是感觉和我的OnlineTool EmojiMix很相似? 没错,我就是看到这个项目后,发现这个项目使用React实现,而我使用Vue + Nuxt进行了复刻。
为什么说是重磅选手呢?其实是因为它还开源了:
同时,整理了Google Emoji Kitchen的直链文件:
2024.02.09 这个大文件已经被移动到CI/CD 里再下载了,可以查看这次
commit
: Move large file download to CI/CD
如果大家想复刻和实现更好的Emoji Mix,可以参考这个项目。
知道了那里可以体验到合成的Emoji;有没有小伙伴还是想知道两个Emoji,如何变成一个复合Emoji呢?
实际上,如果你查看Google Emoji Kitchen 页面的源码,你会发现:
也就是,我们可以把它当作API地址
,对其进行请求得到我们的Emoji合成图片。
如何获得Emoji的Unicode字典,并且判断那些Emoji相互组合,Google Emoji Kitchen有对应的Emoji合成图片呢?我们就可以使用重磅选手提供的metadata.json
字典:
下滑可以发现更多惊喜:
在data
内,我们就可以看到哪两个Emoji组成可以合成新的Emoji。于是,我们就可以使用Python,对这个文件进行解析。
另外,正如上文所说,metadata.json
已经被移动到CI/CD里,也就是在构建这个React项目并部署的时候,才会进行下载:
所以,如果你想查看metadata.json
,可以直接访问下载地址。
首先是解析原版的Emoji,其实我们可以直接用metadata.json
里面的knownSupportedEmoji
进行数据提取。但是我另辟蹊径了一下……
既然我们是准备使用knownSupportedEmoji
配合API地址,请求出Emoji的SVG文件。为什么我们不直接下载渲染好的Emoji SVG文件呢?
所以,再次回到我们的重磅选手
:https://emojikitchen.dev/;这次我们不查看Github仓库,直接访问页面,并且打开 F12 开发者调试,查看页面内容:
你可以发现,所有的Emoji SVG已经在页面的div
内展示,并且每个元素包含SVG的地址:
<li class="MuiImageListItem-root css-kxftp1" style="height: auto; grid-column-end: span 1; grid-row-end: span 1;"><img loading="lazy" width="32px" height="32px" alt="stuck_out_tongue" src="https://raw.githubusercontent.com/googlefonts/noto-emoji/main/svg/emoji_u1f61b.svg" class="MuiImageListItem-img"></li>
很简单啦,我们只需要复制这个div
,直接使用正则表达式提取所有链接并下载即可(SVG_RAW为div
内容):
pattern = r'src="(.*?\.svg)"'
matches = re.findall(pattern, SVG_RAW)
最后下载的结果:
在Vue上进行展示,我们需要对文件名字符串做一些处理,主要是根据长度,对©️ 和 ®️ 进行长度截取:
<img loading="lazy" :alt="`Emoji_${item.item}`"
:src="`/img/emoji/svg/emoji_u${item.item.split('-')
.filter((x) => x !== 'fe0f')
.map((x) => x.padStart(4, '0')) // Handle ©️ and ®️
.join('_')}.svg`"
:class="!ignoreDisable && item.disabled ? 'opacity-30 cursor-not-allowed':'cursor-pointer hover:scale-150 transition-transform duration-150 ease-in-out'"
class="w-8 rounded-lg hover:ring-2 hover:ring-blue-200 hover:bg-amber-50/10 cursor-pointer
hover:scale-150 transition-transform duration-150 ease-in-out"/>
当时这样似乎不是很智能,每次都要人手动访问网站,F12复制元素,能不能更加智能一些?免去手动打开浏览器的操作?
这个时候,我们就可以引入selenium,自动让Python自动调用浏览器:
from bs4 import BeautifulSoup
from selenium import webdriver
def scan_svg_raw():
options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)
driver.get("https://emojikitchen.dev/")
# 等待5秒让页面完全渲染
time.sleep(5)
# 获取页面源代码
page_source = driver.page_source
# 关闭浏览器
driver.quit()
soup = BeautifulSoup(page_source, 'html.parser')
# 找到第一个 class 为 "MuiBox-root css-1uithqi" 的 div
target_div = soup.find('div', class_='MuiBox-root css-1uithqi')
# 获取该 div 内的全部内容
content = target_div.prettify()
# 将内容写入文件
with open('source/svg_raw.txt', 'w', encoding='utf-8') as file:
file.write(content)
有小伙伴可能会问,为什么不用requests
库呢? 这个就要说了,网站实际是React渲染的,在页面使用JavaScript加载完成前,页面只有一个<div id="root"></div>
的占位符,并没有实际内容:
原始的Emoji已经解析完成,合成后的Emoji呢?这次就不要再“造轮子”,直接使用metadata.json
里的内容即可,但是这里还是提一下我的方法。
最初metadata.json
里的内容是这样的:
可以看到,体积比现在50MB版本的小很多;可能是官方觉得,他们的服务器性能比较好,所以在新版本metadata.json
内,直接暴露了合成后的Emoji Kitchen地址:
那么,我基于初代版本,是如何处理的呢?其实很简单:
def get_download_url(json_object):
root_png_dir = 'pngs/' + json_object['date'] + '/'
if not os.path.exists(root_png_dir):
os.makedirs(root_png_dir)
left = "-".join(["u" + part.lower() for part in json_object['leftEmoji'].split("-")])
right = "-".join(["u" + part.lower() for part in json_object['rightEmoji'].split("-")])
date = json_object['date']
return f'https://www.gstatic.com/android/keyboard/emojikitchen/{date}/{left}/{left}_{right}.png'
是不是还算巧妙?
json_object
作为输入,并从中提取date
、leftEmoji
和rightEmoji
的值。然后,它根据这些值构建了一个用于下载的URL的文件路径。下载URL以格式化字符串的形式返回。
当然,面对新版本的metadata.json
,我们可以直接获取JSON内的data
内,每个对象combinations
数组内的gStaticUrl
内容:
def get_download_url_from_metadata():
with open(JSON_FILE_FULL, 'r') as f:
# 读取整个文件内容
json_data = json.load(f)['data']
# 遍历"data"内的对象
for obj in json_data.values():
# 获取每个对象的"combinations"数组
combinations = obj['combinations']
# 遍历"combinations"数组
for combination in combinations:
# 获取每个组合的"gStaticUrl"属性
static_url = combination['gStaticUrl']
# 添加下载任务到Aria2内进行多线程异步下载
add_mission_to_aria2(static_url)
好啦,本次的Emoji Mix复刻介绍就到这里啦。
总的来说,解决了Emoji Kitchen的一些小痛点。虽然实现的过程可能比较麻烦,但是实现的结果可以让更多人体会到Emoji表情的内涵,也是挺不错的。与此同时,也是使用Python进行数据清洗的小小Demo。
大家新年快乐,希望Emoji的合成,能给大家再增添一些欢乐。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。