我有一个程序可以将QGraphicsScene
的内容绘制到PNG图像中。我发现在某些情况下PNG图像没有正确创建。生成的图像似乎“偏移”了一些,因为QGraphicsScene
的左上角不在PNG图像中的(0,0)。
下面的代码演示了这个问题。 createImage
函数创建给定宽度和高度的QGraphicsScene
,在坐标(0,0)处绘制与场景具有相同宽度和高度的纯红色矩形,将此场景渲染为图像,将图像写入文件。我相信这个函数应该总是写出一个纯红色的图像,无论它的宽度和高度如何。但是,here是一个示例输出图像,表明情况并非如此。
testImage
函数(依赖于PIL)读入图像并检查最右边的列和底行。如果图像被错误地“偏移”,它将在底行或最右列中的某处找到白色像素。如果图像已正确生成,则底行和最右列将仅包含红色像素。 (PIL不是问题的一部分;我只是用它来自动测试输出图像。)
#!/usr/bin/env python
import sys
import Image # Requires PIL
from PyQt4.QtCore import Qt, QRect, QRectF
from PyQt4.QtGui import QPen, QBrush, QGraphicsScene, QGraphicsView, QGraphicsRectItem, QPixmap, QPainter, QApplication
whitebrush = QBrush(Qt.white)
redbrush = QBrush(Qt.red)
RED = (255, 0, 0)
def createImage(width, height):
scene = QGraphicsScene(0, 0, width, height)
scene.setBackgroundBrush(whitebrush)
rectangle = QGraphicsRectItem(0, 0, width, height)
rectangle.setPen(QPen(Qt.NoPen))
rectangle.setBrush(redbrush)
rectangle.show()
scene.addItem(rectangle)
view = QGraphicsView()
view.setScene(scene)
outputimg = QPixmap(width, height)
painter = QPainter(outputimg)
targetrect = QRectF(0, 0, width, height)
sourcerect = QRect(0, 0, width, height)
view.render(painter, targetrect, sourcerect)
outputimg.save("output.png", "PNG")
painter.end()
def testImage(width, height):
image = Image.open("output.png")
ok = True
for x in range(width):
if image.getpixel((x, height - 1)) == RED:
if x > 0:
print "First red pixel on bottom row is at x = %d" % x
ok = False
break
else:
print "No red pixels found on bottom row"
ok = False
for y in range(height):
if image.getpixel((width - 1, y)) == RED:
if y > 0:
print "First red pixel in rightmost column is at y = %d" % y
ok = False
break
else:
print "No red pixels found in rightmost column"
ok = False
if ok:
print "Image OK"
def doTest(width, height):
createImage(width, height)
testImage(width, height)
if __name__ == "__main__":
app = QApplication(sys.argv)
doTest(int(sys.argv[1]), int(sys.argv[2]))
以下是一些示例运行:
$ ./qgraphicssceneimagetest.py 200 200 No red pixels found on bottom row No red pixels found in rightmost column
在这种情况下,“偏移”的效果是如此剧烈,以至于整个输出图像都是白色的。
$ ./qgraphicssceneimagetest.py 400 400 First red pixel on bottom row is at x = 117 First red pixel in rightmost column is at y = 37
这是生成我上面链接的样本图像的情况。
$ ./qgraphicssceneimagetest.py 500 500 First red pixel on bottom row is at x = 55
此时,图像现在可以垂直偏移,但红色矩形仍然被绘制为距离右侧55个像素。
$ ./qgraphicssceneimagetest.py 600 600 First red pixel on bottom row is at x = 5
现在几乎正确......
$ ./qgraphicssceneimagetest.py 700 700 Image OK
因此,如果图像足够大,代码似乎可以正确生成输出图像。
碰巧,我有解决这个问题的方法。如果我替换行
,我可以获得createImage
函数来正确创建图像
sourcerect = QRect(0, 0, width, height)
与
xoff = 0
yoff = 0
if width <= 634 and height <= 474:
xoff = (634 - width) // 2
yoff = (474 - height) // 2
elif width < 610:
xoff = (610 - width) // 2
elif height < 450:
yoff = (450 - height) // 2
sourcerect = QRect(xoff, yoff, width, height)
我不知道此代码中“魔术”数字的重要性是什么。但是,我已经使用此解决方法运行了大量测试,并验证它们都生成了正确的纯红色图像。
有了这个解决方法是可以的,但我想了解为什么这些图像没有正确创建。有没有我错过或忘记做的事情?
答案 0 :(得分:2)
发生的事情是,视图会自动计算场景的矩形,然后将自身居中于已添加的图形项目。根据物品的尺寸,有时可能会在边缘留下空白区域。
解决方案是为场景显式设置矩形:
view = QGraphicsView()
view.setScene(scene)
view.setSceneRect(QRectF(view.viewport().rect()))