用Python计算字符串的像素大小 [英] Calculating the pixel size of a string with Python

查看:805
本文介绍了用Python计算字符串的像素大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Python脚本,需要计算任意字体显示的任意字符串的确切大小,以生成简单的图表。我可以很容易地用Tkinter做到。

 导入Tkinter为tk 
导入tkFont
root = tk。 Tk()
canvas = tk.Canvas(root,width = 300,height = 200)
canvas.pack()
(x,y)=(5,5)$ b $ (times,12),(times,24)]中的(family,size)b $ text =yellow world
fonts = []

font = tkFont.Font(family = family,size = size)
(w,h)=(font.measure(text),font.metrics(linespace))
print%s%s: (x,y,x + w,y + h)
canvas.create_text(x,y, text = text,font = font,anchor = tk.NW)
fonts.append(font)#保存垃圾收集对象
y + = h + 5
tk.mainloop()

结果似乎取决于Python和/或系统的版本:

Python 2.5 Mac 0S X,时间12:(63,12),次数24 :(128,24)。 Python 2.6 Mac OS X,时间12:(64,14),时间24:(127,27)。 Python 2.6 Windows XP,时间12:(78,19),次数24:(169,36)http://grab.by/grabs/d24a5035cce0d8032ea4e04cb8c85959.png



在Ned Batchelder提到它之后,我发现字体的大小因平台而异。只要你坚持与Tkinter保持一致,这可能不是一个交易破坏者。但是,我的完整程序并不 使用Tkinter来执行实际绘图:它只是依靠字体大小计算来生成输出(在SVG中或作为Python脚本发送到 Nodebox )。在这里,事情变得非常糟糕:

输出mocodo http://grab.by/grabs/f67b951d092dd1f4f490e1469a53bca2.png



<请注意

我现在怀疑这种差异是不能用Tkinter避免的。你会推荐哪种其他的跨平台解决方案?解析方案

你有两个问题。让我们一次解决它们一个:

1:python 2.5和2.6在同一个平台上使用相同字体的区别



这两个版本的python使用不同版本的tk。在我的Mac机器上,2.5使用tk版本8.4.19和2.6使用8.5.7。在tk的8.5.2版本中,tk的字体测量功能发生了一些变化。假设这些改变是改进的,我认为可以肯定的是,从python 2.6得到的数字比从2.5得到的数字更准确。

<2> Mac上的python 2.6和PC上的2.6。


显然,从包含的屏幕截图中,PC使用更大的字体,因此您可以获得更大的测量值。问题是,为什么?您正在指定点(1/72英寸)的字体大小。为了Tk(或任何渲染系统)渲染字体,它需要知道在实际显示器上有多少像素在一英寸。这将在不同的系统上有所不同,Tk并不总是由底层操作系统给出一个准确的数字来进行计算。从历史上看,苹果和微软已经标准化了72ppi和96ppi,不管实际显示如何,所以数字总是不一样的。有关Mac和Windows如何计算像素密度的差异的更多信息,请参阅每英寸点数关于维基百科的文章。



您可以尝试通过以像素而不是点来指定字体来解决这个问题。你可以使用字体大小的负数来做到这一点。



最后,你可能会添加一个小例子代码,就是打印出 font.actual()命令 - 你可能会在你的Windows和Mac机器上看到不同的东西,这可以解释它们之间的差异。这告诉你Tk正在使用哪种字体。

I have a Python script which needs to calculate the exact size of arbitrary strings displayed in arbitrary fonts in order to generate simple diagrams. I can easily do it with Tkinter.

import Tkinter as tk
import tkFont
root = tk.Tk()
canvas = tk.Canvas(root, width=300, height=200)
canvas.pack()
(x,y) = (5,5)
text = "yellow world"
fonts = []
for (family,size) in [("times",12),("times",24)]:
    font = tkFont.Font(family=family, size=size)
    (w,h) = (font.measure(text),font.metrics("linespace"))
    print "%s %s: (%s,%s)" % (family,size,w,h)
    canvas.create_rectangle(x,y,x+w,y+h)
    canvas.create_text(x,y,text=text,font=font,anchor=tk.NW)
    fonts.append(font) # save object from garbage collecting
    y += h+5
tk.mainloop()

The results seem to depend on the version of Python and/or the system:

Python 2.5 Mac 0S X, times 12: (63,12), times 24: (128,24). Python 2.6 Mac OS X, times 12: (64,14), times 24: (127,27). Python 2.6 Windows XP, times 12: (78,19), times 24: (169,36) http://grab.by/grabs/d24a5035cce0d8032ea4e04cb8c85959.png

After Ned Batchelder mentioned it, I discovered that the size of fonts differs from platform to platform. It may not be a deal breaker as long as you stick with Tkinter, which remains consistent with itself. But my complete program does not use Tkinter to perform the actual drawing: it just relies on its font size calculations to generate an output (in SVG or as a Python script to be sent to Nodebox). And it's there that things go really wrong:

Output of mocodo http://grab.by/grabs/f67b951d092dd1f4f490e1469a53bca2.png

(Please look at the image in real size. Note that the main font used for these outputs is not Times, but Trebuchet MS.)

I now suspect that such discrepancies can't be avoided with Tkinter. Which other cross-platform solution would you recommend?

解决方案

You have two problems. Let's tackle them one at a time

1: the difference between python 2.5 and 2.6 on the same platform with the same font

These two versions of python use different versions of tk. On my mac box, 2.5 uses tk version 8.4.19 and 2.6 uses 8.5.7. In version 8.5.2 of tk were some changes to the font measurement features of tk. Assuming that the changes were improvements, I think it's safe to assume that the numbers you get from python 2.6 are more accurate than the ones from 2.5.

2: the difference between python 2.6 on the mac and 2.6 on the PC.

Obviously, from the screenshots you include, the PC is using a larger font and thus you get larger numbers for the measurement. The question is, why? You are specifying the font size in points (1/72 of an inch). In order for Tk (or any rendering system) to render the font, it needs to know how many pixels are in an inch on the actual display. This will vary on different systems, and Tk isn't always given an accurate number by the underlying OS in order to do its calculations.

Historically, Apple and Microsoft have standardized on 72ppi and 96ppi regardless of the actual display, so the numbers are always going to be different. For more information about the differences in how the mac and windows calculate pixel density see the Dots Per Inch article on wikipedia.

You might try solving this by specifying a font in pixels rather than in points. You can do this by using negative numbers for the font size.

Finally, one thing you might add to your little example code is to print out the result of the font.actual() command -- you might see something different between your windows and mac boxes, which would explain the differences there. This tells you exactly which font is being used by Tk.

这篇关于用Python计算字符串的像素大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆