当我尝试渲染 png 时,text_extends 表现出意外,这是一个错误吗?
我最近注意到,在某些情况下,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]
I noticed lately that in some cases the png will look differently as the pdf. I rendered the preview images in different sizes an realized that the output could be totally different for the same input when I change the output size of the surface.
The problem is, that text_extends reports different normalized sizes for the same text when the surface pixel size is different. In this example the width varies from 113.861 to 120.175. Since I have to write each line separately those errors are some times much bigger in total.
Has anybody an idea how avoid those miscalculation?
Here is a small demonstration of this problem
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]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这种行为可能是由于文本渲染本身的性质造成的 - 因为字体中的字形根据像素分辨率以不同的方式绘制。与字形大小相比,当像素分辨率较小时更是如此(我想说每个字形的高度小于 30px)。这种行为在某种程度上是可以预料的——总是为了优先考虑文本的可读性。如果它太偏离 - 或者 png 文本比 PDF 上的“丑陋”(而不是尺寸不正确),那么 iis 是开罗的一个错误。尽管如此,您可能应该将这个确切的问题放在 Cairo 的问题跟踪器上,以便开发人员可以判断它是否是一个错误(如果是,这可能是他们了解它的唯一可能的方法)
(显然他们没有公共错误跟踪器 - 只需通过电子邮件将其发送到 [电子邮件受保护] < /a> )
至于您的具体问题,我建议您的解决方法是将文本渲染到更大的表面(可能大 5 倍),然后调整该表面的大小并将内容粘贴到原始表面上(如果需要的话) )。通过这种方式,您可以避免由于每个字形可用像素数量的限制而导致字形大小变化(代价是最终输出的文本渲染效果较差)。
This behavior is likely due to the nature of text rendering itself - as glyphs in a font depend are drawn in different ways, depending on the pixel resolution. More so when the pixel resolution is small when compared to the glyph sizes (I'd say less than 30px height per glyph). This behavior is to be expected to some extend - always in order to prioritize readability of the text. If it is too off - or the png text is "uglier" than on the PDF (instead of incorrect size), then iis a bug in Cairo. Nevertheless, you probably should place this exact question on Cairo's issue tracker, so that the developers can tell wether it is a bug or not (and if it is, it maybe the only possible way for they to get aware of it)
(Apparently they have no public bug tracker - just e-mail it to [email protected] )
As for your specific problem, the workaround I will suggest to you is to render your text to a larger surface -- maybe 5 times larger, and resize that surface and paste the contents on your original surface (if needed at all). This way you might avoid glyph-size variations due to constraints in the number of pixels available for each glyph (at the cost of having a poorer text rendering on your final output).