ImageFont's getsize() does not get correct text size?
I use the following two methods to to generate text preview image for a .ttf font file
PIL method:
def make_preview(text, fontfile, imagefile, fontsize=30):
try:
font = ImageFont.truetype(fontfile, fontsize)
text_width, text_height = font.getsize(text)
img = Image.new('RGBA', (t开发者_JAVA技巧ext_width, text_height))
draw = ImageDraw.Draw(img)
draw.text((0, 0), text, font=font, fill=(0, 0, 0))
return True
except:
return False
ImageMagick method:
def make_preview(text, fontfile, imagefile, fontsize=30):
p = subprocess.Popen(['convert', '-font', fontfile, '-background',
'transparent', '-gravity', 'center', '-pointsize', str(fontsize),
'-trim', '+repage', 'label:%s' % text, image_file])
return p==0
Both methods create correct preview images most of time but in some rare cases (<2%), the font.getsize(text) just cannot get the correct text size which result in text overflowed provided canvas. ImageMagick has same problem.
Sample fonts and previews:
HANFORD.TTF http://download.appfile.com/HANFORD.png
NEWTOW.TTF http://download.appfile.com/NEWTOW.png
MILF.TTF http://download.appfile.com/MILF.png
SWANSE.TTF http://download.appfile.com/SWANSE.png
I have looked into ImageMagick's documentations and found the explanation of this problem at http://www.imagemagick.org/Usage/text/#overflow.
Is it possible to detect such text overflows and draw text to fit the canvas as we expected?
Not a programming solution, but when I regenerate your problem, its only happens on your fonts (other fonts like Arial is no problem at all), so I have fixed your font files (by changing ascent/decent metrics). you can download here,
And sorry about Hanford Script Font, its not perfect as you see, height seems ok, but left side is not get drawed, its out of my understanding.
UPDATE: Regarding Hanford Font, Here is a work around, pass extra space in text like " Handford Script", and then crop the extra space in image like img=img.crop(img.getbbox())
alt text http://img64.imageshack.us/img64/1903/hanfordfontworkaround.jpg
UPDATE2:I had to pass color=(255,255,255) in Image.New to get Black Text on White background
img = Image.new('RGBA', (text_width, text_height),color=(255,255,255))
I had a similar issue once in PHP and ImageMagick.
In the end, I solved this by drawing the text on a very large canvas, and then trimming it using the trim/auto-crop functions that shave extra space off the image.
If I understand your preview function right, it is actually already doing exactly that: It should be enough to just remove the width and height settings.
In this case, just specify ImageMagick to use a larger canvas size with a fixed font size and it will draw text at specified point size while keeping its integrity.
def make_preview(text, fontfile, imagefile, fontsize=30):
p = subprocess.call(['convert', '-font', fontfile, '-background',
'transparent', '-gravity', 'center', '-size', '1500x300',
'-pointsize', str(fontsize), '-trim', '+repage', 'label:%s' % text, image_file])
return p==0
If you need to fit text into specified canvas rather than using a fixed point size, you may need to resize the output image after it's created.
PIL doesn't do this very well drawing exotic fonts, no matter what point size you specify to load a font, it always overflows text outside output image.
精彩评论