我希望favicon.ico
从 Python 以编程方式创建文件,但 PIL 仅支持读取ico
文件。
7 回答
您可以使用枕头:
from PIL import Image
filename = r'logo.png'
img = Image.open(filename)
img.save('logo.ico')
或者,您可以指定所需的图标大小:
icon_sizes = [(16,16), (32, 32), (48, 48), (64,64)]
img.save('logo.ico', sizes=icon_sizes)
Pillow 文档说默认情况下它会生成大小
,[(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (255, 255)]
并且任何大于原始大小或 255 的大小都将被忽略。
是的,它位于文档的只读部分,但它在某种程度上有效。
也许以下方法会起作用:
- 使用 PIL 生成图标图像
- 使用ImageMagick、 PythonMagick的python接口将图像转换为.ico格式
我没有尝试过这种方法。ImageMagick convert 命令行程序能够将 .png 文件转换为 .ico 格式,因此至少 ImageMagick 支持 .ico 格式。
虽然这个问题比较老了,但它是使用 Python 将 PNG 文件转换为 ICO 的突出搜索结果,所以我想我会加两分钱。
如果你想要的只是一个图标,Douglas Leeder 的回答对我来说似乎很好。如果您有一个高分辨率的徽标 PNG 文件,并且想要将其转换为 ICO 文件,那么 Ronan Paixão 的答案可能是最简单的方法。
但是一个 ICO 文件可以包含多个图像,用于不同的分辨率,我经常发现自己想要对这些不同的分辨率进行细粒度控制,以避免不幸的抗锯齿效果,这意味着我想提供每个图像分辨率单独。这意味着我不想将单个,而是多个 PNG 文件转换为单个 ICO 文件。据我所知,枕头包不提供这种能力。幸运的是,现代 ICO 文件可以包含多个 PNG 文件,因此任务归结为编写一些标题条目的简单挑战。根据情况,我写了两个函数,第一个基本上是 Ronan Paixão 的解决方案,而第二个提供了将多个 PNG 文件合并为一个 ICO 文件的功能:
from pathlib import Path
from PIL import Image
def bake_one_big_png_to_ico(sourcefile, targetfile, sizes=None):
"""Converts one big PNG into one ICO file.
args:
sourcefile (str): Pathname of a PNG file.
targetfile (str): Pathname of the resulting ICO file.
sizes (list of int): Requested sizes of the resulting
icon file, defaults to [16, 32, 48].
Use this function if you have one big, square PNG file
and don’t care about fine-tuning individual icon sizes.
Example::
sourcefile = "Path/to/high_resolution_logo_512x512.png"
targetfile = "Path/to/logo.ico"
sizes = [16, 24, 32, 48, 256]
bake_one_big_png_to_ico(sourcefile, targetfile, sizes)
"""
if sizes is None:
sizes = [16, 32, 48]
icon_sizes = [(x, x) for x in sizes]
Image.open(sourcefile).save(targetfile, icon_sizes=icon_sizes)
def bake_several_pngs_to_ico(sourcefiles, targetfile):
"""Converts several PNG files into one ICO file.
args:
sourcefiles (list of str): A list of pathnames of PNG files.
targetfile (str): Pathname of the resulting ICO file.
Use this function if you want to have fine-grained control over
the resulting icon file, providing each possible icon resolution
individually.
Example::
sourcefiles = [
"Path/to/logo_16x16.png",
"Path/to/logo_32x32.png",
"Path/to/logo_48x48.png"
]
targetfile = "Path/to/logo.ico"
bake_several_pngs_to_ico(sourcefiles, targetfile)
"""
# Write the global header
number_of_sources = len(sourcefiles)
data = bytes((0, 0, 1, 0, number_of_sources, 0))
offset = 6 + number_of_sources * 16
# Write the header entries for each individual image
for sourcefile in sourcefiles:
img = Image.open(sourcefile)
data += bytes((img.width, img.height, 0, 0, 1, 0, 32, 0, ))
bytesize = Path(sourcefile).stat().st_size
data += bytesize.to_bytes(4, byteorder="little")
data += offset.to_bytes(4, byteorder="little")
offset += bytesize
# Write the individual image data
for sourcefile in sourcefiles:
data += Path(sourcefile).read_bytes()
# Save the icon file
Path(targetfile).write_bytes(data)
该代码假定您的 PNG 文件是 32-Bit-per-Pixel RGBA 图像。否则,上面代码中的数字 32 将不得不更改,并应替换为一些 Pillow-image-sniffing。
如果你有imageio,(可能是在 Python 中读取/写入图像的最佳库),你可以使用它:
import imageio
img = imageio.imread('logo.png')
imageio.imwrite('logo.ico', img)
安装非常简单
pip install imageio
我不知道这是否适用于所有情况,但在 WinXP 上,.ico 可以是大小为 16x16、32x32 或 64x64 的 bmp。只需将扩展名从 bmp 更改为 ico 即可。
我试图将我的徽标批量转换为我的基于 python 的应用程序与fbs打包的多种尺寸,并最终根据上述答案使用下面的方法来执行此操作。
甚至在 Windows 中生成并显示的 .ico 也能完美运行。在 Linux 中,它显示一个 Icon.ico 已压缩,但不必太担心,因为它只会在 Windows 中使用。
from PIL import Image
icon_sizes = [(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (255, 255)]
image = Image.open('/some/path/to/logo-python/logo.png')
fileoutpath = '/some/path/to/logo-python/'
for size in icon_sizes:
print(size[0])
fileoutname = fileoutpath + str(size[0]) + ".png"
new_image = image.resize(size)
new_image.save(fileoutname)
new_logo_ico_filename = fileoutpath + "Icon.ico"
new_logo_ico = image.resize((128, 128))
new_logo_ico.save(new_logo_ico_filename, format="ICO",quality=90)