31

我希望favicon.ico从 Python 以编程方式创建文件,但 PIL 仅支持读取ico文件。

4

7 回答 7

63

您可以使用枕头

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 的大小都将被忽略。

是的,它位于文档的只读部分,但它在某种程度上有效。

于 2016-03-23T01:49:37.393 回答
8

也许以下方法会起作用:

我没有尝试过这种方法。ImageMagick convert 命令行程序能够将 .png 文件转换为 .ico 格式,因此至少 ImageMagick 支持 .ico 格式。

于 2008-09-05T10:36:58.273 回答
6

根据维基百科,现代浏览器可以处理 PNG 格式的网站图标,所以也许你可以生成它?

或者,ICO文章描述了格式......

于 2008-09-05T13:35:32.900 回答
3

虽然这个问题比较老了,但它是使用 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。

于 2019-11-08T16:47:47.057 回答
2

如果你有imageio,(可能是在 Python 中读取/写入图像的最佳库),你可以使用它:

import imageio

img = imageio.imread('logo.png')
imageio.imwrite('logo.ico', img)

安装非常简单

pip install imageio
于 2018-09-14T14:25:03.403 回答
1

我不知道这是否适用于所有情况,但在 WinXP 上,.ico 可以是大小为 16x16、32x32 或 64x64 的 bmp。只需将扩展名从 bmp 更改为 ico 即可。

于 2008-09-05T10:38:00.533 回答
0

我试图将我的徽标批量转换为我的基于 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)
于 2020-06-14T14:52:58.073 回答