Есть ли библиотека Python для генерации.ico файлов?
Я ищу, чтобы создать favicon.ico
файлы программно из Python, но PIL поддерживает только чтение ico
файлы.
5 ответов
Согласно Википедии, современные браузеры могут обрабатывать значки в формате PNG, так что, может быть, вы могли бы просто сгенерировать это?
Альтернативно статья ICO описывает формат...
Вы можете использовать подушку:
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
- Преобразование изображения в формат.ico с использованием интерфейса Python для ImageMagick, PythonMagick
Я не пробовал этот подход. Программа командной строки ImageMagick convert смогла преобразовать файл.png в формат.ico, поэтому, по крайней мере, ImageMagick поддерживает формат.ico.
Хотя этот вопрос довольно старый, это выдающийся результат поиска по использованию Python для преобразования файлов PNG в ICO, поэтому я решил добавить свои два цента.
Если все, что вам нужно, это фавикон, ответ Дугласа Лидера мне кажется идеальным. Если у вас есть один PNG-файл с высоким разрешением вашего логотипа и вы хотите преобразовать его в файл ICO, ответ Ронана Пайшё, вероятно, будет самым простым способом.
Но файл ICO может содержать несколько изображений, предназначенных для разных разрешений, и я часто оказывался в ситуации, когда мне хотелось иметь точный контроль над этими различными разрешениями, чтобы избежать нежелательных эффектов сглаживания, что означает, что я хочу предоставить разрешение каждого изображения индивидуально. Это означает, что я хочу преобразовать не один, а несколько файлов PNG в один файл ICO. Насколько я понимаю, пакет Pillow не предоставляет такой возможности. К счастью, современный файл ICO может содержать внутри несколько файлов PNG, поэтому задача сводится к простой задаче написания некоторых записей заголовков. В зависимости от ситуации я написал две функции, первая из которых в основном является решением Ронана Пайшё, а вторая обеспечивает функциональность для объединения нескольких файлов 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 представляют собой изображения RGBA с 32-битным разрешением. В противном случае число 32 в приведенном выше коде пришлось бы изменить и заменить на какое-нибудь обнюхивание подушечки.
Если у вас есть imageio(вероятно, лучшая библиотека для чтения / записи изображений в Python), вы можете использовать ее:
import imageio
img = imageio.imread('logo.png')
imageio.imwrite('logo.ico', img)
Установить так же просто, как
pip install imageio
Я не знаю, применимо ли это ко всем случаям, но в WinXP.ico может иметь размер 16x16, 32x32 или 64x64. Просто измените расширение на ico с bmp, и вы готовы к работе.
Я пытался пакетно преобразовать свой логотип в несколько размеров для моего приложения на основе Python, упакованного с помощью fbs, и в итоге использовал приведенное ниже, чтобы сделать это на основе приведенных выше ответов.
отлично работал, даже сгенерированный.ico и показанный в Windows. В 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)