Welcome, guest | Sign In | My Account | Store | Cart

PIL does not allow resizing default bitmap font. This code resizes it by itself.

The disadvantage is slow speed but the advantage is it becomes possible to set color of each pixel of text foreground and background.

As an example I set foreground to reverse colors and background to grayscale.

Python, 50 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# Draw (Bitmap Font) Text to Image
from PIL import Image, ImageDraw, ImageFont

def reverseColor(r, g, b):
    return (255 - r, 255 - g, 255 - b)
def grayscaleColor(r, g, b):
    a = (r + g + b) / 3
    return (a, a, a)

text = "Hello World!"
# textColor = (255, 255, 0) # RGB Yellow
# textBackgroundColor = (255, 0, 0) # RGB Red
textX = 400 # text width in pixels
textY = 100 # text height in pixels
textTopLeftX = 0
textTopLeftY = 0

# create new image
# imgx = 800 # image width in pixels
# imgy = 600 # image height in pixels
# image = Image.new("RGB", (imgx, imgy))

# load image
image = Image.open("input.png")
(imgx, imgy) = image.size
# image = image.resize((imgx, imgy), Image.BICUBIC)

font = ImageFont.load_default() # load default bitmap font
(width, height) = font.getsize(text)
textImage = font.getmask(text)
pixels = image.load()
for y in range(imgy):
    by = int(height * (y - textTopLeftY) / textY + 0.5)
    if by >= 0 and by < height:
        for x in range(imgx):
            bx = int(width * (x - textTopLeftX) / textX + 0.5)
            if bx >= 0 and bx < width:
                if textImage.getpixel((bx, by)) == 0: # text background
                    # pass # transparent background
                    # pixels[x, y] = textBackgroundColor
                    # (r, g, b, a) = pixels[x, y]
                    (r, g, b) = pixels[x, y]
                    pixels[x, y] = grayscaleColor(r, g, b)
                else: # text foreground
                    # pixels[x, y] = textColor                
                    # (r, g, b, a) = pixels[x, y]
                    (r, g, b) = pixels[x, y]
                    pixels[x, y] = reverseColor(r, g, b)

image.save("output.png", "PNG")

2 comments

Jet 6 years, 4 months ago  # | flag

Don't know, if that is a error, but changing: (r, g, b, a) = pixels[x, y] to (r, g, b) = pixels[x, y]

it will work. With four parameters it end with error: ValueError: need more than 3 values to unpack

FB36 (author) 6 years, 4 months ago  # | flag

Fixed. I didn't notice that problem when I had posted this code. Maybe my test image had rgba values instead of rgb.

Created by FB36 on Sun, 25 Jan 2015 (MIT)
Python recipes (4591)
FB36's recipes (148)

Required Modules

Other Information and Tasks