feat:可以阅读gif
This commit is contained in:
@@ -1,14 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [0.6.0] - 2025-3-30
|
## [0.6.0] - 2025-4-4
|
||||||
### 🌟 核心功能增强
|
### 🌟 核心功能增强
|
||||||
#### 架构重构
|
#### 架构重构
|
||||||
- 将MaiBot重构为MaiCore独立智能体
|
- 将MaiBot重构为MaiCore独立智能体
|
||||||
- 移除NoneBot相关代码,改为插件方式与NoneBot对接
|
- 移除NoneBot相关代码,改为插件方式与NoneBot对接
|
||||||
- 精简代码结构,优化文件夹组织
|
|
||||||
- 新增详细统计系统
|
|
||||||
|
|
||||||
#### 思维流系统
|
#### 思维流系统
|
||||||
|
- 提供两种聊天逻辑,思维流聊天(ThinkFlowChat)和推理聊天(ReasoningChat)
|
||||||
- 新增思维流作为实验功能
|
- 新增思维流作为实验功能
|
||||||
- 思维流大核+小核架构
|
- 思维流大核+小核架构
|
||||||
- 思维流回复意愿模式
|
- 思维流回复意愿模式
|
||||||
@@ -21,6 +20,8 @@
|
|||||||
#### 回复系统
|
#### 回复系统
|
||||||
- 优化回复逻辑,添加回复前思考机制
|
- 优化回复逻辑,添加回复前思考机制
|
||||||
- 移除推理模型在回复中的使用
|
- 移除推理模型在回复中的使用
|
||||||
|
- 更改了回复引用的逻辑,从基于时间改为基于新消息
|
||||||
|
- 提供私聊的PFC模式,可以进行有目的,自由多轮对话
|
||||||
|
|
||||||
#### 记忆系统优化
|
#### 记忆系统优化
|
||||||
- 优化记忆抽取策略
|
- 优化记忆抽取策略
|
||||||
@@ -31,6 +32,13 @@
|
|||||||
- 修复relationship_value类型错误
|
- 修复relationship_value类型错误
|
||||||
- 优化关系管理系统
|
- 优化关系管理系统
|
||||||
- 改进关系值计算方式
|
- 改进关系值计算方式
|
||||||
|
- 修复并重启了关系系统
|
||||||
|
|
||||||
|
#### 表情包系统
|
||||||
|
- 可以识别gif表情包
|
||||||
|
- 修复了表情包的注册,获取和发送逻辑
|
||||||
|
- 表情包增加存储上限
|
||||||
|
- 自动清理缓存图片
|
||||||
|
|
||||||
### 💻 系统架构优化
|
### 💻 系统架构优化
|
||||||
#### 配置系统改进
|
#### 配置系统改进
|
||||||
@@ -83,6 +91,7 @@
|
|||||||
- 优化cmd清理功能
|
- 优化cmd清理功能
|
||||||
- 改进LLM使用统计
|
- 改进LLM使用统计
|
||||||
- 优化记忆处理效率
|
- 优化记忆处理效率
|
||||||
|
- 增加了调试信息
|
||||||
|
|
||||||
### 📚 文档更新
|
### 📚 文档更新
|
||||||
- 更新README.md内容
|
- 更新README.md内容
|
||||||
@@ -93,6 +102,7 @@
|
|||||||
|
|
||||||
### 🔧 其他改进
|
### 🔧 其他改进
|
||||||
- 新增神秘小测验功能
|
- 新增神秘小测验功能
|
||||||
|
- 新增详细统计系统
|
||||||
- 新增人格测评模型
|
- 新增人格测评模型
|
||||||
- 优化表情包审查功能
|
- 优化表情包审查功能
|
||||||
- 改进消息转发处理
|
- 改进消息转发处理
|
||||||
@@ -111,8 +121,6 @@
|
|||||||
5. 加强WebUI功能
|
5. 加强WebUI功能
|
||||||
6. 完善部署文档
|
6. 完善部署文档
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.5.15] - 2025-3-17
|
## [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
|
## [test-0.6.0-snapshot-8] - 2025-4-3
|
||||||
- 修复了表情包的注册,获取和发送逻辑
|
- 修复了表情包的注册,获取和发送逻辑
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import hashlib
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import io
|
import io
|
||||||
|
import math
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
from ...common.database import db
|
from ...common.database import db
|
||||||
@@ -112,8 +114,13 @@ class ImageManager:
|
|||||||
return f"[表情包:{cached_description}]"
|
return f"[表情包:{cached_description}]"
|
||||||
|
|
||||||
# 调用AI获取描述
|
# 调用AI获取描述
|
||||||
prompt = "这是一个表情包,使用中文简洁的描述一下表情包的内容和表情包所表达的情感"
|
if image_format == "gif" or image_format == "GIF":
|
||||||
description, _ = await self._llm.generate_response_for_image(prompt, image_base64, image_format)
|
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")
|
cached_description = self._get_description_from_db(image_hash, "emoji")
|
||||||
if cached_description:
|
if cached_description:
|
||||||
@@ -221,6 +228,72 @@ class ImageManager:
|
|||||||
logger.error(f"获取图片描述失败: {str(e)}")
|
logger.error(f"获取图片描述失败: {str(e)}")
|
||||||
return "[图片]"
|
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()
|
image_manager = ImageManager()
|
||||||
|
|||||||
Reference in New Issue
Block a user