是否有用于生成 .ico 文件的 Python 库?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 19:26:40  来源:igfitidea点击:

Is there a Python library for generating .ico files?

pythonfavicon

提问by Hank Gay

I'm looking to create favicon.icofiles programatically from Python, but PIL only has support for reading icofiles.

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

采纳答案by Douglas Leeder

According to Wikipediamodern browsers can handle favicons in PNG format, so maybe you could just generate that?

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

Alternatively the ICO articledescribes the format...

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

回答by Ronan Paix?o

You can use Pillow:

您可以使用枕头

from PIL import Image
filename = r'logo.png'
img = Image.open(filename)
img.save('logo.ico')

Optionally, you may specify the icon sizes you want:

或者,您可以指定所需的图标大小:

icon_sizes = [(16,16), (32, 32), (48, 48), (64,64)]
img.save('logo.ico', sizes=icon_sizes)

The Pillow docssay that by default it will generate sizes [(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (255, 255)]and any size bigger than the original size or 255 will be ignored.

枕头文档说,在默认情况下它会产生大小 [(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (255, 255)]和任何规模大小比原来的大小或255将被忽略更大。

Yes, it is in the Read-onlysection of the docs, but it works to some extent.

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

回答by codeape

Perhaps the following would work:

也许以下方法可行:

  • Generate your icon image using PIL
  • Convert the image to .ico format using the python interface to ImageMagick, PythonMagick
  • 使用 PIL 生成图标图像
  • 使用python接口将图像转换为.ico格式到ImageMagick、PythonMagick

I have not tried this approach. The ImageMagick convert command line program was able to convert a .png file to .ico format, so at least ImageMagick supports the .ico format.

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

回答by Overdrivr

If you have imageio, (probably the best library for reading/writing images in Python), you can use it:

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

import imageio

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

Install is as easy as

安装很简单

pip install imageio

回答by Jan

Although this question is rather old, it's a prominent search result for using Python to convert PNG files to ICO, so I thought I'll add my two cents.

虽然这个问题比较老,但它是使用 Python 将 PNG 文件转换为 ICO 的突出搜索结果,所以我想我会加两分钱。

If all you want is a favicon, Douglas Leeder's answer seems perfectly fine to me. If you have one high-resolution PNG file of your logo and want to convert it to an ICO file, the answer of Ronan Paix?o is probably the easiest way to go.

如果你想要的只是一个网站图标,Douglas Leeder 的回答对我来说似乎非常好。如果您有一个高分辨率的徽标 PNG 文件并想将其转换为 ICO 文件,Ronan Paix?o 的答案可能是最简单的方法。

But an ICO file can contain multiple images, intended for different resolutions, and I often found myself in the situation of wanting to have fine-grained control over these different resolutions, to avoid unfortunate anti-aliasing effects, which means that I want to provide each image resolution individually. Which means that I want to convert not a single, but multiple PNG files into a single ICO file. As far as I can see, the Pillow package doesn't provide this capability. Fortunately, a modern ICO file can contain multiple PNG files inside, so the task boils down to the simple challenge of writing some header entries. Depending on the situation, I wrote two functions, the first one basically the solution of Ronan Paix?o, while the second one provides the functionality to join several PNG files into one ICO file:

但是一个 ICO 文件可以包含多个图像,用于不同的分辨率,我经常发现自己处于想要对这些不同分辨率进行细粒度控制的情况,以避免不幸的抗锯齿效果,这意味着我想提供每个图像分辨率单独。这意味着我不想将单个而是多个 PNG 文件转换为单个 ICO 文件。据我所知, Pillow 包不提供此功能。幸运的是,现代 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)

The code presupposes that your PNG files are 32-Bit-per-Pixel RGBA images. Otherwise, the number 32 in the above code would have to be changed and should be replaced with some Pillow-image-sniffing.

该代码假定您的 PNG 文件是每像素 32 位的 RGBA 图像。否则,必须更改上述代码中的数字 32,并应替换为一些 Pillow-image-sniffing。

回答by thing2k

I don't know if this applies for all cases, but on WinXP an .ico can be a bmp of size 16x16, 32x32 or 64x64. Just change the extension to ico from bmp and you're ready to go.

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