这个图库是来自历年官方活动或者联名活动的表情包,有动态有静态。































以下是我自己编辑的表情包,主要是修改B站的静态表情包。





















网站将逐步切换到WebP格式图片,今天捣鼓了插件在服务器端替换图片,但WP的媒体库却怎么都搞不定了,媒体库会自动生成很多缩略图用于不同的场景,我不想碰它的缩略图生成效果,因此只写单一的转换代码是没法做出完整的效果的。
退而求其次使用本地对图片进行处理,该脚本使用PIL库,图片分辨率限制为2560最长/宽,可以处理带透明通道的图片,也可以处理GIF,用下来效果还不错。
1月8日更新:
【Python】使用WebP官方库进行WebP转换
【Python】使用cwebp、gif2webp、exiftool实现保留exif信息的WebP转换
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageSequence
import os
def resize_image(img):
max_size = 2560
width, height = img.size
if width > max_size or height > max_size:
if width > height:
new_width = max_size
new_height = int((new_width / width) * height)
else:
new_height = max_size
new_width = int((new_height / height) * width)
img = img.resize((new_width, new_height), Image.LANCZOS)
return img
def convert_to_webp(input_path):
try:
file_extension = os.path.splitext(input_path)[1].lower()
output_path = os.path.splitext(input_path)[0] + ".webp"
if not os.path.exists(input_path):
raise FileNotFoundError(f"文件 {input_path} 不存在,请检查路径。")
if file_extension == '.webp':
return f"文件 {input_path} 已是 WebP 格式,无需转换。"
with Image.open(input_path) as img:
if file_extension in ['.gif'] and getattr(img, "is_animated", False):
frames = []
durations = []
for frame in ImageSequence.Iterator(img):
# 处理透明度
if frame.mode == "P":
frame = frame.convert("RGBA")
# 转换帧为 RGBA 并存储
new_frame = frame.copy()
frames.append(new_frame)
durations.append(frame.info.get('duration', 100))
# 重复最后一帧
if len(frames) > 1:
durations[-1] = max(durations[-1], 100)
# 保存为动态 WebP
frames[0].save(
output_path,
format="WEBP",
save_all=True,
append_images=frames[1:],
duration=durations,
loop=img.info.get('loop', 0), # 循环次数
transparency=0, # 确保透明度保留
quality=85
)
else:
# 静态图片处理
if img.mode == "P":
if "transparency" in img.info:
img = img.convert("RGBA")
else:
img = img.convert("RGB")
img = resize_image(img)
if img.mode != "RGBA":
img = img.convert("RGBA")
img.save(output_path, format="WEBP", quality=85)
return f"图片已转换并保存为 {output_path}"
except Exception as e:
return f"处理文件时发生错误: {e}"
def select_files():
file_paths = filedialog.askopenfilenames(
title="选择图片文件",
filetypes=[("所有图片格式", "*.jpg;*.jpeg;*.png;*.gif;*.webp;*.bmp;*.tiff"),
("JPEG 图片", "*.jpg;*.jpeg"),
("PNG 图片", "*.png"),
("GIF 图片", "*.gif"),
("WebP 图片", "*.webp"),
("BMP 图片", "*.bmp"),
("TIFF 图片", "*.tiff")]
)
if file_paths:
for path in file_paths:
file_listbox.insert(tk.END, path)
def convert_and_save_batch():
files = file_listbox.get(0, tk.END)
if not files:
messagebox.showerror("错误", "请选择至少一个图片文件!")
return
results = []
for file_path in files:
result = convert_to_webp(file_path)
results.append(result)
messagebox.showinfo("完成", "\n".join(results))
def clear_list():
file_listbox.delete(0, tk.END)
root = tk.Tk()
root.title("批量图片转换为 WebP 工具")
root.geometry("600x400")
frame = tk.Frame(root)
frame.pack(pady=10, padx=10, fill=tk.BOTH, expand=True)
scrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL)
file_listbox = tk.Listbox(frame, selectmode=tk.EXTENDED, yscrollcommand=scrollbar.set)
scrollbar.config(command=file_listbox.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
file_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
button_frame = tk.Frame(root)
button_frame.pack(pady=10)
select_button = tk.Button(button_frame, text="选择文件", command=select_files, width=15)
select_button.grid(row=0, column=0, padx=5)
clear_button = tk.Button(button_frame, text="清空列表", command=clear_list, width=15)
clear_button.grid(row=0, column=1, padx=5)
convert_button = tk.Button(button_frame, text="批量转换", command=convert_and_save_batch, width=15)
convert_button.grid(row=0, column=2, padx=5)
root.mainloop()