Sådan genereres kvalitetsvinduer ikoner med billeder af store bogstaver inde ved hjælp af Python?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil have 26 filer (for startere): A.ico, B.ico, ... Z.ico, hvor de består af 16x16 256-farvebillede og et 32x32 256-farvebillede, hvor farven på teksten er sort, og skrifttypen er ... siger Calibri, og størrelsen - det passer bedst til torget. Jeg vil gerne gøre dette ved hjælp af Python Image Library, hvis det er muligt.


Jeg ved, at jeg nok kan få mine ikoner på andre måder, men jeg vil gerne lære at bruge PIL bedre, og vil gerne bruge det til opgaven ved hånden.

Bedste reference


Start med et stort blankt billede og tegn tegnet i midten af ​​det. Find tegnets kanter og udtrække et firkant fra billedet, der indeholder hele tegnet. Brug funktionen thumbnail med indstillingen ANTIALIAS for at reducere den til den nødvendige 16x16 eller 32x32 størrelse. Derefter reducere antallet af farver til 256: Sådan reduceres farvepaletten med PIL

Andre referencer 1


Dette er baseret på svaret fra @Mark Ransom. Tak, Mark!
Dette fungerede for mig, selvom 'blackify' -funktionen stadig er ufuldkommen.
Jeg skal stadig finde ud af, hvordan man opretter en .ico-fil uden at bruge icotool til Linux. [5]


# 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!')