74 lines
2.9 KiB
Python
74 lines
2.9 KiB
Python
from PIL import Image, ImageEnhance, ImageFilter
|
|
|
|
def convert_png_to_ico(png_path, ico_path, sizes=None, resample=Image.LANCZOS, sharpen=False):
|
|
"""
|
|
将PNG图片转换为ICO图标文件,同时优化圆角效果
|
|
|
|
参数:
|
|
- png_path: 输入PNG文件路径
|
|
- ico_path: 输出ICO文件路径
|
|
- sizes: 图标尺寸列表
|
|
- resample: 重采样方法,默认为Image.LANCZOS
|
|
- sharpen: 是否应用锐化滤镜
|
|
"""
|
|
if sizes is None:
|
|
sizes = [(16, 16), (32, 32), (48, 48), (64, 64), (256, 256)]
|
|
|
|
try:
|
|
with Image.open(png_path) as img:
|
|
# 确保图片为RGBA模式
|
|
if img.mode != 'RGBA':
|
|
img = img.convert('RGBA')
|
|
|
|
# 检查是否有透明通道
|
|
has_transparency = False
|
|
if img.mode == 'RGBA':
|
|
alpha = img.getchannel('A')
|
|
if alpha.getextrema()[0] < 255:
|
|
has_transparency = True
|
|
|
|
# 为每个尺寸创建单独的图像
|
|
icon_sizes = []
|
|
for size in sizes:
|
|
# 调整图片尺寸
|
|
if size[0] < img.size[0] or size[1] < img.size[1]:
|
|
# 缩小图片时使用高质量重采样算法
|
|
resized_img = img.resize(size, resample=resample)
|
|
else:
|
|
# 放大图片时使用NEAREST算法避免模糊(适用于需要清晰边缘的情况)
|
|
resized_img = img.resize(size, resample=Image.NEAREST)
|
|
|
|
# 应用锐化滤镜(可选)
|
|
if sharpen:
|
|
enhancer = ImageEnhance.Sharpness(resized_img)
|
|
resized_img = enhancer.enhance(1.5) # 增强锐度
|
|
|
|
icon_sizes.append(resized_img)
|
|
|
|
# 保存为ICO文件
|
|
if len(icon_sizes) > 0:
|
|
# 使用第一个尺寸作为主图标
|
|
icon_sizes[0].save(
|
|
ico_path,
|
|
format='ICO',
|
|
sizes=[(img.size[0], img.size[1]) for img in icon_sizes]
|
|
)
|
|
print(f"成功将 {png_path} 转换为 {ico_path}")
|
|
print(f"包含尺寸: {sizes}")
|
|
if has_transparency:
|
|
print("注意:已保留图片的透明通道(圆角效果)")
|
|
else:
|
|
print("图片没有检测到透明通道(可能没有圆角效果)")
|
|
else:
|
|
print("错误:未指定有效尺寸")
|
|
|
|
except Exception as e:
|
|
print(f"转换失败: {e}")
|
|
|
|
if __name__ == "__main__":
|
|
# 输入和输出文件路径
|
|
png_path = 'app.png'
|
|
ico_path = 'favicon.ico'
|
|
|
|
# 调用函数进行转换,禁用锐化处理
|
|
convert_png_to_ico(png_path, ico_path, sizes=[(256, 256)], sharpen=False) |