当我尝试渲染一个png时,text_extends表现出意外,这是一个错误吗?

时间:2011-06-01 13:39:38

标签: png cairo pycairo

我最近注意到在某些情况下,png的外观与pdf不同。我渲染了不同大小的预览图像,意识到当我改变表面的输出大小时,相同输入的输出可能完全不同。

问题是,当表面像素大小不同时,text_extends会报告同一文本的不同标准化大小。在此示例中,宽度从113.861到120.175不等。由于我必须分别编写每一行,这些错误总共要大一些。

有人知道如何避免这些错误的估算?

以下是此问题的小型演示

import cairo
form StringIO import StringIO

def render_png(width, stream):
    width_px = height_px = width
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width_px, height_px)
    cr = cairo.Context(surface)
    cr.scale(float(width_px) / float(100),
             float(height_px) / float(100))
    cr.set_antialias(cairo.ANTIALIAS_GRAY)

    cr.set_source_rgb (1, 1, 1)
    cr.rectangle(0, 0, 100, 100) 
    cr.fill()

    cr.select_font_face('Zapfino Extra LT') # a fancy font
    cr.set_font_size(20)
    example_string = 'Ein belieber Test Text'
    xbearing, ybearing, width, height, xadvance, yadvance = (
                        cr.text_extents(example_string))
    xpos = (100. - width) / 2. # centering text
    print width

    cr.move_to(xpos,50)
    cr.set_source_rgba(0,0,0)
    cr.show_text(example_string)

    surface.write_to_png(stream)
    return width

if __name__ == '__main__':
    l=[]
    for i in range(100,150,1):
        outs=StringIO()
        xpos = render_png(i,outs)
        l.append((i,xpos))
        #out = open('/home/hwmrocker/Desktop/FooBar/png_test%03d.png'%i, 'w')
        #outs.seek(0)
        #out.write(outs.read())
        #out.close()

    from operator import itemgetter
    l=sorted(l,key=itemgetter(1))
    print
    print l[0]
    print l[-1]

1 个答案:

答案 0 :(得分:0)

这种行为可能是由于文本呈现本身的性质 - 因为字体依赖的字形是以不同的方式绘制的,具体取决于像素分辨率。当像素分辨率与字形大小相比较小时(我说每个字形的高度小于30px),更是如此。这种行为在某种程度上是可以预期的 - 总是为了优先考虑文本的可读性。如果太过 - 或者png文本比PDF更粗糙(而不是不正确的大小),那么我在开罗是一个错误。不过,你可能应该把这个确切的问题放在Cairo的问题跟踪器上,这样开发人员就可以告诉它是否是一个bug(如果是的话,它可能是他们了解它的唯一可行方法) (显然他们没有公共错误跟踪器 - 只需发送电子邮件至cairo-bugs@cairographics.org)

至于你的具体问题,我建议的解决方法是将文本渲染到更大的表面 - 可能大5倍,并调整表面大小并将内容粘贴到原始表面上(如果需要的话) 。这样,您可以避免由于每个字形可用像素数量的限制而导致的字形大小变化(代价是在最终输出上呈现较差的文本)。