ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Nonebot2插件:逝世表情包(1)

2022-05-21 19:04:30  阅读:195  来源: 互联网

标签:Nonebot2 插件 逝世 group pic event user import id


前言已经懒得写辣,总之把入门教程官方文档都看一遍

纯小白,排版混乱,逻辑重复,代码屎山,随时跑路

广告 长期招租,快来404群玩(720053992)

0.废话文集

搓表情包的想法之前看群里的bot可以生成就好想搞了,只是一直鸽——

总之官方商店里有强大的petpet和memes两个插件,已经足够满足大部分的表情包生成需求了(实际看下来常用的就两三个)

代码全copy(bushi
总而言之,这篇将会是实现的是下面这个表情包

嘿嘿

0.5 水准备

使用了python的PIL(pillow)库来生成图片,(openCV的对着类似实现函数做下就好了吧)

用到了requests库(用于获取用户头像)

1.startswith!

设定的指令触发格式为"设定的命令起始符+找+@用户/qq号码+需要填写的字段(非必须)"

使用on_command() 作为事件响应器

大概前面
import nonebot
import requests
from nonebot.rule import *
from nonebot import *
from nonebot.plugin import on_keyword
from nonebot.adapters.onebot.v11 import Bot, Event, MessageEvent, GroupMessageEvent
from nonebot.adapters.onebot.v11.message import Message
import os
import re
import PIL
from PIL import Image, ImageDraw, ImageFont


async def handle_rule(bot: Bot, event: Event) -> bool:
    with open("白名单群聊txt", encoding='utf-8') as file:  # 提取白名单群文件中的群号
        white_block = []
        for line in file:
            line = line.strip()
            line = re.split("[ |#]", line)  # 可能会有'#'注释或者空格分割
            white_block.append(line[0])  # 新建一个表给它扔进去
    try:
        whatever, group_id, user_id = event.get_session_id().split('_')  # 获取当前群聊id,发起人id,返回的格式为group_groupid_userid
    except:  # 如果上面报错了,意味着发起的是私聊,返回格式为userid
        group_id = None
        user_id = event.get_session_id()
    if group_id in white_block or group_id == None:
        return True
    else:
        return False


ct_pic_find = on_command({"找"}, rule=handle_rule, priority=50)


@ct_pic_find.handle()
async def ct_pic_find_handle(bot: Bot, event: Event):
    try:
        whatever, group_id, user_id = event.get_session_id().split('_')  # 获取当前群聊id,发起人id,返回的格式为group_groupid_userid
        data = await bot.call_api('get_group_member_list', **{
            'group_id': int(group_id)
        })
    except:  # 如果上面报错了,意味着发起的是私聊,返回格式为userid
        group_id = None
        user_id = event.get_session_id()
    find_message = str(event.get_message()).replace('/找', '').split()
    '''
    nb2会过滤消息段中的第一个@自己的消息,所以那自己bot试的注意下(比如我查了半天报错)
    上面这段按照指令格式进行分段
    '''
    if "[CQ" in find_message[0]:  # 简单粗暴地判断下第一个分类是不是@类
        for sbwwww in event.get_message():
            if sbwwww.type == 'at':
                pic_id = sbwwww.data['qq']
                break  # 读取完第一个退出即可
        '''
        Nb2的Messagement类会可以直接提取cq码的类型
        这样就可以直接获取@的对象了
        https://github.com/botuniverse/onebot-11/tree/master/message
        Nb2的Message适配Onebot v11协议,所以好好看看上面的文档吧
        同样的,file(图片缓存名称和地址),flash(闪照)等等都会用到
        下面这段是还没啃透时自己的写法,使用正则匹配获取@的id号码(要用\转义下[])
        pic_id = re.search('(?<=\[CQ:at,qq=).*?(?=\])', find_message[0]).group()
        '''
    else:  # 如果不是@的人的形式,判断是否为中间给定的是否为QQ号的形式
        try:
            if find_message[0].isnumeric():  # 判断是否为全为数字字符
                pic_id = find_message[0]
            else:
                await ct_pic_find.finish(Message("你找谁啊...."))
        except:
            await ct_pic_find.finish(Message("你找谁啊...."))
    try:
        pic_name = find_message[1]  # 接着获取名字(请问看见xxx了吗)
    except:
        pic_name = ''
    if pic_name == '':  # 如果用户没有输入想要生成的名字,那么默认为群聊昵称,其次为QQ昵称
        if isinstance(event, GroupMessageEvent):  # 判断是否为群聊事件
            for j in data:
                if str(j['user_id']) == pic_id:  # 如果想找的人在群聊内
                    if j['card'] != '':  # 判断是否存在群昵称,并赋值
                        pic_name = j['card']
                    else:
                        pic_name = j['nickname']
        if pic_name == '':  # 如果是私聊事件或者不在群聊内
            data = await bot.call_api('get_stranger_info',
                                      **{'user_id': int(pic_id)})  # 参考go-cqhttp的官方api说明,获取陌生人的相关个人资料
            pic_name = data['nickname']
    user_name = pic_name

接着来对图片进行处理,示例中的表情包是(900,800),其中用户头像为(600,600),字号使用为("simhei", 50)

点我看代码~
user_url = f"http://q1.qlogo.cn/g?b=qq&nk={pic_id}&s=640"
'''
这个url获取的是任意一个用户的高清头像,pic_id就是指定的QQ号,之后会常用
'''
picfile = requests.get(user_url)
open(f"你头像图片存放的地址", "wb").write(picfile.content)  # 从网上下载图片并保存到本地,若存在会覆写的
user_pic = Image.open(f"你头像图片存放的地址") # 准备复制
user_image = Image.new(mode="RGB", size=(900, 800), color="white") # 生成一块900*800的白色画布,具体自己定
user_pic = user_pic.resize((600, 600)) # 把获取到的用户图片resize一下,因为大部分图片并不是600*600
user_image.paste(user_pic, (150, 100)) # 放到指定位置,按照自己预留给文字的位置算一下(下面所有的涉及到位置的都建议使用自己的喜好)
# 添加文字
draw = ImageDraw.Draw(user_image)
font = ImageFont.truetype("simhei", 50)
word = f'请问你们看见{user_name}了吗' # 文案自己定
w, h = font.getsize(word) # 获取指定大小和文本后的字段长度,用于生成居中字体
# 参数:位置、文本、填充、字体
draw.text(xy=((900 - w) / 2, (100 - h) / 2), text=word, fill='black', font=font)
word = '非常可爱,简直是小天使,让大家都看看'
w, h = font.getsize(word)
draw.text(xy=((900 - w) / 2, 700 + (100 - h) / 2), text=word, fill='black', font=font)
user_image.save(f"生成完的表情包存放的地址")
user_url = f"file:///生成完的表情包存放的地址"
await ct_pic_find.finish(Message(f"[CQ:image,file={user_url},id=40000]"))

示例:大概就头图吧

2.大概问题

  1. 头像的位置大小和想要生成的字体类型都可以按照自己的需求改,只要计算预留出足够的空间即可
  2. 考虑到有的群友id实属逆天(的长度),生成第一行的时候可以考虑先获取总共的字节数,然后按照预留的宽度大小计算出最适合的字体大小(不过更简单的是按比例直接生成更大的画布?)
  3. 对id中的特殊字符不太适应

标签:Nonebot2,插件,逝世,group,pic,event,user,import,id
来源: https://www.cnblogs.com/life-is-a-picnic/p/16295705.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有