开发者

How to generate quality windows icons with images of capital letters inside using Python?

开发者 https://www.devze.com 2023-03-29 05:29 出处:网络
I want to get 26 files (for starters): A.i开发者_如何学Cco, B.ico, ... Z.ico, where they are composed of 16x16 256-color image, and a 32x32 256-color image, where the color of the text is black, and t

I want to get 26 files (for starters): A.i开发者_如何学Cco, B.ico, ... Z.ico, where they are composed of 16x16 256-color image, and a 32x32 256-color image, where the color of the text is black, and the font is ... say Calibri, and the size - whatever fits best into the square. I would like to do this using Python Image Library if possible.

I know that I can probably get my icons through other means, but I would like to learn to use the PIL better, and would like to use it for the task at hand.


Start with a large blank image and draw the character on the center of it. Find the edges of the character and extract a square from the image that includes all of the character. Use the thumbnail function with the ANTIALIAS option to reduce it to the 16x16 or 32x32 size required. Then reduce the number of colors to 256: How to reduce color palette with PIL


This is based on the answer by @Mark Ransom. Thank you, Mark! This worked for me, though the 'blackify' function is imperfect still. I still need to figure out how to create an .ico file without using icotool for Linux.

# This script generates icon files from the two images.
# Uses Python 2.6.5, uses the Python Imaging Library

import Image
import ImageDraw
import ImageFont

letters = [chr(i + ord('A')) for i in range(26)]
default_huge =  ImageFont.load_default()
large_size = 1000
lim = large_size + 1

# Apparently I can use the same size for the font.
calibri_huge = ImageFont.truetype("calibri.ttf", large_size)

def crop_letter(img):
    minx, maxx, miny, maxy = lim, -lim, lim, -lim
    for x in range(large_size):
        for y in range(large_size):
            if sum(img.getpixel((x, y))) == 3 * 255: continue
            # Else, found a black pixel
            minx = min(minx, x)
            maxx = max(maxx, x)
            miny = min(miny, y)
            maxy = max(maxy, y)
    return img.crop(box = (minx, miny, maxx, maxy))

# This works for me 95% of the time
def blackify(color):
    return 255 * (color > 240)

for letter in letters:
    # A bit wasteful, but I have plenty of RAM.
    img = Image.new("RGB", (large_size, large_size), "white")
    draw = ImageDraw.Draw(img)
    draw.text((0,0), letter, font = calibri_huge, fill = "black")

    img32 = crop_letter(img)
    img16 = img32.copy()

    img32.thumbnail((32, 32), Image.ANTIALIAS)
    img16.thumbnail((16, 16), Image.ANTIALIAS)

    img32 = Image.eval(img32, blackify)
    img16 = Image.eval(img16, blackify)

##  Not needed
##    # Apparently this is all it takes to get 256 colors.
##    img32 = img32.convert('P')
##    img16 = img16.convert('P')

    img32.save('icons3/{0}32x32.bmp'.format(letter))
    img16.save('icons3/{0}16x16.bmp'.format(letter))
#    break

print('DONE!')
0

精彩评论

暂无评论...
验证码 换一张
取 消