Nonebot2外掛:逝世表情包(1)
阿新 • • 發佈:2022-05-21
前言已經懶得寫辣,總之把入門教程官方文件都看一遍
純小白,排版混亂,邏輯重複,程式碼屎山,隨時跑路
廣告
長期招租,快來404群玩(720053992)0.廢話文集
搓表情包的想法之前看群裡的bot可以生成就好想搞了,只是一直鴿——
總之官方商店裡有強大的petpet和memes兩個外掛,已經足夠滿足大部分的表情包生成需求了(實際看下來常用的就兩三個)
總而言之,這篇將會是實現的是下面這個表情包
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.大概問題
- 頭像的位置大小和想要生成的字型型別都可以按照自己的需求改,只要計算預留出足夠的空間即可
- 考慮到有的群友id實屬逆天(的長度),生成第一行的時候可以考慮先獲取總共的位元組數,然後按照預留的寬度大小計算出最適合的字型大小(不過更簡單的是按比例直接生成更大的畫布?)
- 對id中的特殊字元不太適應