首页 文章

Python Imaging Library - 文本呈现

提问于
浏览
37

我正在尝试使用PIL渲染一些文本,但坦白说,结果是废话 .

例如,这是我在Photoshop中写的一些文字:

PhotoShop

以及PIL的结果:

PIL

如您所见,PIL的结果不尽如人意 . 也许我只是挑剔,但有没有办法使用PIL绘制文本,使结果更接近我的参考图像?

这是我在Python 2.7和PIL 1.1.7上使用的代码

image = Image.new("RGBA", (288,432), (255,255,255))
usr_font = ImageFont.truetype("resources/HelveticaNeueLight.ttf", 25)
d_usr = ImageDraw.Draw(image)
d_usr = d_usr.text((105,280), "Travis L.",(0,0,0), font=usr_font)

5 回答

  • 18

    我想出了我认为可以接受的解决方案 .

    我所做的是渲染文本大,比如它需要的大小3倍然后缩放它用抗锯齿调整它的大小,它不是100%完美,但它比默认更好,并且不需要cairo或者攀高 .

    例如,

    image = Image.new("RGBA", (600,150), (255,255,255))
    draw = ImageDraw.Draw(image)
    font = ImageFont.truetype("resources/HelveticaNeueLight.ttf", fontsize)
    
    draw.text((10, 0), txt, (0,0,0), font=font)
    img_resized = image.resize((188,45), Image.ANTIALIAS)
    

    你最终得到这个结果,

    final result

    这比我之前使用相同的字体要好得多 .

  • 0

    尝试使用pycairo - Cairo绘图库的python绑定 - 它可用于更精细的绘图,使用抗锯齿线等 - 并且您还可以生成基于矢量的图像

    正确处理字体和布局很复杂,并且还需要使用“pango”和“pangocairo”库 . 虽然它们是用于严肃的字体工作(所有GTK小部件都使用pango进行字体渲染),但是可用的docuemtnation和示例非常差 .

    下面的示例显示系统中可用的打印件,并将示例文本呈现为在命令行上作为参数传递的字体系列 .

    # -*- coding: utf-8 -*-
    import cairo
    import pango
    import pangocairo
    import sys
    
    surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, 320, 120)
    context = cairo.Context(surf)
    
    #draw a background rectangle:
    context.rectangle(0,0,320,120)
    context.set_source_rgb(1, 1, 1)
    context.fill()
    
    #get font families:
    
    font_map = pangocairo.cairo_font_map_get_default()
    families = font_map.list_families()
    
    # to see family names:
    print [f.get_name() for f in   font_map.list_families()]
    
    #context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
    
    # Positions drawing origin so that the text desired top-let corner is at 0,0
    context.translate(50,25)
    
    pangocairo_context = pangocairo.CairoContext(context)
    pangocairo_context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
    
    layout = pangocairo_context.create_layout()
    fontname = sys.argv[1] if len(sys.argv) >= 2 else "Sans"
    font = pango.FontDescription(fontname + " 25")
    layout.set_font_description(font)
    
    layout.set_text(u"Travis L.")
    context.set_source_rgb(0, 0, 0)
    pangocairo_context.update_layout(layout)
    pangocairo_context.show_layout(layout)
    
    with open("cairo_text.png", "wb") as image_file:
        surf.write_to_png(image_file)
    

    Rendred image

  • 11

    我从未使用PIL,但快速浏览Draw方法的文档表明PIL提供了渲染 simple 图形的方法 . Photoshop提供了一种渲染 complex 图形的方法 . 要获得接近类似Photoshop的结果,至少需要字体提示和消除锯齿 . PIL 's documentation doesn'甚至暗示有这样的能力 . 您可能希望使用可能更好地在图像上呈现文本的外部工具 . 例如,ImageMagick(您将需要使用8位版本,它处理标准的24位RGB) . 你可以在这里找到一些文字绘图样本:http://www.imagemagick.org/Usage/draw/

  • 55

    您也可以尝试将字体写入两次,以提高质量 .

    image = Image.new("RGBA", (288,432), (255,255,255))
    usr_font = ImageFont.truetype("resources/HelveticaNeueLight.ttf", 25)
    d_usr = ImageDraw.Draw(image)
    d_usr = d_usr.text((105,280), "Travis L.",(0,0,0), font=usr_font)
    d_usr = d_usr.text((105,280), "Travis L.",(0,0,0), font=usr_font)
    
  • 0

    建议:使用Wand或其他成像库

    这是魔杖的一个例子 -

    from wand.color import Color
    from wand.image import Image
    from wand.drawing import Drawing
    from wand.compat import nested
    from math import cos, pi, sin
    
    with Drawing() as draw:
        with Image(width=1000, height=100, background=Color('lightblue')) as img:
            draw.font_family = 'Indie Flower'
            draw.font_size = 40.0
            draw.push()
            draw.fill_color = Color('hsl(0%, 0%, 0%)')
            draw.text(0,int(img.height/2 + 20), 'Hello, world!')
            draw.pop()
            draw(img)
            img.save(filename='image.png')
    

    image that comes out-

相关问题