为什么QPainter似乎在QImage上使用drawText时无法预测地缩放字体?

时间:2016-01-16 15:36:39

标签: pyqt4 qpainter qimage

我正在使用PyQt4(Linux,Windows,无所谓)将两个单独的图像(一个一个jpg)加载到单独的QImages中。图像均为640x480。

self.image1 = QtGui.QImage('image1.png');
self.image2 = QtGui.QImage('image2.jpg');

当我使用以下代码将文本绘制到每个文本(再次单独)时,生成的文本在大小和位置上有很大差异。

def ImageOverlay( self, img, text):

    #img is a QImage
    #ImageOverlay is called many times so font creation is done once.

    if self.font is None:
        self.font = QtGui.QFont('Sans',16)
        metrics = QtGui.QFontMetrics(self.font)
        self.fontheight = metrics.ascent();

    painter = QtGui.QPainter()
    painter.begin(img)
    painter.setOpacity(1.0)
    painter.setPen(QtCore.Qt.black)
    painter.setFont(self.font)
    painter.drawText( 1,self.fontheight, text )
    painter.end()

然后,使用ImageOverlay()调用修改的每个图像都会加载到QLabel中,并以简单的网格布局显示。

渲染完全不同:

enter image description here

但是,如果我按像素重新设置字体大小(而不是点),它看起来像我期望的那样工作:

    self.font = QtGui.QFont('Sans', 16)
    self.font.setPixelSize(16)

enter image description here

我怀疑它与QImage的一个属性有关,它建议用于呈现文本的某种类型的上下文,但我无法找到发生这种情况的确切原因。

任何人都可以解释为什么会发生这种情况,或者,如果可能的话,请指出一些描述这种行为的文档?

1 个答案:

答案 0 :(得分:2)

QtGui.QFontMetrics(self.font)(字体不是created for a specific paint device)会创建适合您显示分辨率的字体指标,这意味着在使用点和像素大小进行转换时,它会使用显示的dpi值。

当您在QPaintDevice(在您的情况下为QImage)上绘制文字时,画家会使用基于该绘图设备的字体指标。解析度。您可以使用画家访问此指标。 fontMetrics()属性,或使用QFontMetrics(font, paintDevice)构造函数。

如果比较两张图片' image.dotsPerMeterX()image.dotsPerMeterY()值(或在图片编辑器中打开它们并检查其中的分辨率),我确定您会看到不同的值,这意味着其元数据中的图像处理是不同,这就是渲染文本大小不同的原因。

因此,如果您希望文字大小以像素为单位,请坚持使用font.setPixelSize(),如果您对相对于图片设置的文字大小感到满意。 dpi,使用点数字体大小,但使用painter.fontMetrics().ascent()计算文本基线。