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!')
精彩评论