feat:可以阅读gif
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## [0.6.0] - 2025-3-30
|
||||
## [0.6.0] - 2025-4-4
|
||||
### 🌟 核心功能增强
|
||||
#### 架构重构
|
||||
- 将MaiBot重构为MaiCore独立智能体
|
||||
- 移除NoneBot相关代码,改为插件方式与NoneBot对接
|
||||
- 精简代码结构,优化文件夹组织
|
||||
- 新增详细统计系统
|
||||
|
||||
#### 思维流系统
|
||||
- 提供两种聊天逻辑,思维流聊天(ThinkFlowChat)和推理聊天(ReasoningChat)
|
||||
- 新增思维流作为实验功能
|
||||
- 思维流大核+小核架构
|
||||
- 思维流回复意愿模式
|
||||
@@ -21,6 +20,8 @@
|
||||
#### 回复系统
|
||||
- 优化回复逻辑,添加回复前思考机制
|
||||
- 移除推理模型在回复中的使用
|
||||
- 更改了回复引用的逻辑,从基于时间改为基于新消息
|
||||
- 提供私聊的PFC模式,可以进行有目的,自由多轮对话
|
||||
|
||||
#### 记忆系统优化
|
||||
- 优化记忆抽取策略
|
||||
@@ -31,6 +32,13 @@
|
||||
- 修复relationship_value类型错误
|
||||
- 优化关系管理系统
|
||||
- 改进关系值计算方式
|
||||
- 修复并重启了关系系统
|
||||
|
||||
#### 表情包系统
|
||||
- 可以识别gif表情包
|
||||
- 修复了表情包的注册,获取和发送逻辑
|
||||
- 表情包增加存储上限
|
||||
- 自动清理缓存图片
|
||||
|
||||
### 💻 系统架构优化
|
||||
#### 配置系统改进
|
||||
@@ -83,6 +91,7 @@
|
||||
- 优化cmd清理功能
|
||||
- 改进LLM使用统计
|
||||
- 优化记忆处理效率
|
||||
- 增加了调试信息
|
||||
|
||||
### 📚 文档更新
|
||||
- 更新README.md内容
|
||||
@@ -93,6 +102,7 @@
|
||||
|
||||
### 🔧 其他改进
|
||||
- 新增神秘小测验功能
|
||||
- 新增详细统计系统
|
||||
- 新增人格测评模型
|
||||
- 优化表情包审查功能
|
||||
- 改进消息转发处理
|
||||
@@ -111,8 +121,6 @@
|
||||
5. 加强WebUI功能
|
||||
6. 完善部署文档
|
||||
|
||||
|
||||
|
||||
## [0.5.15] - 2025-3-17
|
||||
### 🌟 核心功能增强
|
||||
#### 关系系统升级
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
这里放置了测试版本的细节更新
|
||||
## [test-0.6.0-snapshot-9] - 2025-4-4
|
||||
- 可以识别gif表情包
|
||||
|
||||
## [test-0.6.0-snapshot-8] - 2025-4-3
|
||||
- 修复了表情包的注册,获取和发送逻辑
|
||||
|
||||
@@ -5,6 +5,8 @@ import hashlib
|
||||
from typing import Optional
|
||||
from PIL import Image
|
||||
import io
|
||||
import math
|
||||
import numpy as np
|
||||
|
||||
|
||||
from ...common.database import db
|
||||
@@ -112,8 +114,13 @@ class ImageManager:
|
||||
return f"[表情包:{cached_description}]"
|
||||
|
||||
# 调用AI获取描述
|
||||
prompt = "这是一个表情包,使用中文简洁的描述一下表情包的内容和表情包所表达的情感"
|
||||
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, image_format)
|
||||
if image_format == "gif" or image_format == "GIF":
|
||||
image_base64 = self.transform_gif(image_base64)
|
||||
prompt = "这是一个动态图表情包,每一张图代表了动态图的某一帧,黑色背景代表透明,使用中文简洁的描述一下表情包的内容和表达的情感,简短一些"
|
||||
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, "jpg")
|
||||
else:
|
||||
prompt = "这是一个表情包,使用中文简洁的描述一下表情包的内容和表情包所表达的情感"
|
||||
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, image_format)
|
||||
|
||||
cached_description = self._get_description_from_db(image_hash, "emoji")
|
||||
if cached_description:
|
||||
@@ -221,6 +228,72 @@ class ImageManager:
|
||||
logger.error(f"获取图片描述失败: {str(e)}")
|
||||
return "[图片]"
|
||||
|
||||
def transform_gif(self, gif_base64: str) -> str:
|
||||
"""将GIF转换为水平拼接的静态图像
|
||||
|
||||
Args:
|
||||
gif_base64: GIF的base64编码字符串
|
||||
|
||||
Returns:
|
||||
str: 拼接后的JPG图像的base64编码字符串
|
||||
"""
|
||||
try:
|
||||
# 解码base64
|
||||
gif_data = base64.b64decode(gif_base64)
|
||||
gif = Image.open(io.BytesIO(gif_data))
|
||||
|
||||
# 收集所有帧
|
||||
frames = []
|
||||
try:
|
||||
while True:
|
||||
gif.seek(len(frames))
|
||||
frame = gif.convert('RGB')
|
||||
frames.append(frame.copy())
|
||||
except EOFError:
|
||||
pass
|
||||
|
||||
if not frames:
|
||||
raise ValueError("No frames found in GIF")
|
||||
|
||||
# 计算需要抽取的帧的索引
|
||||
total_frames = len(frames)
|
||||
if total_frames <= 15:
|
||||
selected_frames = frames
|
||||
else:
|
||||
# 均匀抽取10帧
|
||||
indices = [int(i * (total_frames - 1) / 14) for i in range(15)]
|
||||
selected_frames = [frames[i] for i in indices]
|
||||
|
||||
# 获取单帧的尺寸
|
||||
frame_width, frame_height = selected_frames[0].size
|
||||
|
||||
# 计算目标尺寸,保持宽高比
|
||||
target_height = 200 # 固定高度
|
||||
target_width = int((target_height / frame_height) * frame_width)
|
||||
|
||||
# 调整所有帧的大小
|
||||
resized_frames = [frame.resize((target_width, target_height), Image.Resampling.LANCZOS)
|
||||
for frame in selected_frames]
|
||||
|
||||
# 创建拼接图像
|
||||
total_width = target_width * len(resized_frames)
|
||||
combined_image = Image.new('RGB', (total_width, target_height))
|
||||
|
||||
# 水平拼接图像
|
||||
for idx, frame in enumerate(resized_frames):
|
||||
combined_image.paste(frame, (idx * target_width, 0))
|
||||
|
||||
# 转换为base64
|
||||
buffer = io.BytesIO()
|
||||
combined_image.save(buffer, format='JPEG', quality=85)
|
||||
result_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
|
||||
|
||||
return result_base64
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"GIF转换失败: {str(e)}")
|
||||
return None
|
||||
|
||||
|
||||
# 创建全局单例
|
||||
image_manager = ImageManager()
|
||||
|
||||
Reference in New Issue
Block a user