Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw character with gradient colors using PIL?

I have the function that generates character images from a font file using PIL. For the current example, it generates a white background image and a red character text. What I want now is that instead of pure red or any other color I can generate a gradient color. Is this possible with my current code? I have seen this post but it didn't help me.

Edit 1:

Currently, I am generating English alphabet images from font files using PIL. The fonts variable in my code has N number of ".ttf" files. lets suppose N=3 all in different styles e.g. style1, style2, style3. My current code will always generate these N different styles with fixed white background and fixed red character color. As shown in the below figure.

Style1

Style2

Style3

Instead of red color for the characters, I would like to apply gradients for each style. i.e. all characters in style1 font images should have the same gradient, style 2 font style should have a different gradient from style1 characters but should be the same for all of its characters and so on. As shown below (styles are different from the above images. Its just for demonstration of what I want).

gradient Style1

gradient Style2

gradient Style3

My code so far:

fonts = glob.glob(os.path.join(fonts_dir, '*.ttf'))
for font in fonts:
  image = Image.new('RGB', (IMAGE_WIDTH, IMAGE_HEIGHT), color='white')
  font = ImageFont.truetype(font, 150)
  drawing = ImageDraw.Draw(image)
  w, h = drawing.textsize(character, font=font)
  drawing.text(
  ((IMAGE_WIDTH-w)/2, (IMAGE_HEIGHT-h)/2),
  character,
  fill='red',
  font=font
  )
  image.save(file_path, 'PNG')
like image 709
Ammar Ul Hassan Avatar asked Aug 04 '20 11:08

Ammar Ul Hassan


1 Answers

One fairly easy way of doing it is to draw the text in white on a black background and then use that as the alpha/transparency channel over a background with a gradient.

Here's a background gradient:

enter image description here

#!/usr/bin/env python3

from PIL import Image, ImageDraw, ImageFont

w, h = 400, 150
image = Image.open('gradient.jpg').rotate(90).resize((w,h))
font = ImageFont.truetype('/System/Library/Fonts/MarkerFelt.ttc', 80)

# Create new alpha channel - solid black
alpha = Image.new('L', (w,h))
draw = ImageDraw.Draw(alpha)
draw.text((20,10),'Some Text',fill='white',font=font)
alpha.save('alpha.png')

# Use text cutout as alpha channel for gradient image
image.putalpha(alpha)
image.save('result.png')
 

The alpha.png looks like this:

enter image description here

And the result.png looks like this:

enter image description here

Note that the area around the text is transparent. but you can easily paste it onto a white or black background. So, say you wanted the background yellow, add the following to the bottom of the code above:

solid = Image.new('RGB', (w,h), 'yellow')
solid.paste(image,image)
solid.save('result2.png')

enter image description here

like image 166
Mark Setchell Avatar answered Nov 03 '22 05:11

Mark Setchell