0

I have QGraphicsPixmapItem from loaded image(6000x4000 pixel) which is added to QGraphicsScene. I added several filled square and using addRect on scene.

How I can save edited image with a high resolution as full-size image

Here is my code

class PhotoViewer(QGraphicsView):
    def __init__(self, parent):
        self._zoom = 0
        self._items = []
        self._scene = QGraphicsScene(self)
        self._photo = QGraphicsPixmapItem()
        self._scene.addItem(self._photo)
        self.setScene(self._scene)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setBackgroundBrush(QBrush(QColor(30, 30, 30)))
        self.setFrameShape(QFrame.NoFrame)
        # some other actions

    def fitInView(self, scale=True):
        rect = QRectF(self._photo.pixmap().rect())
        if not rect.isNull():
            self.setSceneRect(rect)
        # custom fit in view and scaling

    def setPhoto(self, pixmap=None):
        self._zoom = 0
        if pixmap and not pixmap.isNull():
            self._empty = False
            self._photo.setPixmap(pixmap)
        self.fitInView()

    def add_a_Rectangle(self):
        self._added = self._scene.addRect(rect,pen)
        # custom other code

    def save_image(self):
        #====method that I need to implement=======#
        pass

class MainWindow(QMainWindow):
    def __init__(self):
        self.viewer_edit = PhotoViewer(self)
    def save_img(self):
        self.viewer_edit.save_img()
        pass

And I tried two ways, But It's not working
First

img = QPixmap(self._scene.grab())
painter = QPainter(img)
painter.setRenderHint(QPainter.Antialiasing)
self._scene.render(painter)
painter.end()
img.save('D:\\test.png')

Result

loaded image's size is 3000x3000 pixel, but Result image's size is 1881x768 pixel.

Second

I used to refer to How to render a part of QGraphicsScene and save It as image file PyQt5 and eyllanesc's comment.

w = self._photo.boundingRect().width()
h = self._photo.boundingRect().height()
image = QImage(int(w),int(h), QImage.Format_ARGB32_Premultiplied)
painter = QPainter(image)
self._scene.render(painter,QRectF(0, 0,w,h), self._photo.boundingRect())
painter.end()
image.save('D:\\test2.png',quality=100)

Finally I solved the problem

jin1ib
  • 1
  • 2
  • From what I understand, if you have placed an image of MxN pixels you want an image with the same size but that has the modification (in your example part of the rectangle should be shown) Am I correct? – eyllanesc Mar 26 '20 at 15:56
  • 1
    Also, in what failed the second approach? QGraphicsScene's [`render()`](https://doc.qt.io/qt-5/qgraphicsscene.html#render) should work. – musicamante Mar 26 '20 at 16:00
  • have you tried using `quality=100` argument to save? Documentation states that otherwise `default quality` is used. I don't know if that will change anything https://doc.qt.io/qt-5/qpixmap.html#save – dgan Mar 26 '20 at 16:02
  • Explains the following: *I tried to find a method in QGraphicsScene that can extract image from it, but failed.*, what does it mean to fail? – eyllanesc Mar 26 '20 at 16:05
  • For me you have not used the second method correctly, if you provide an MRE of how you have used the second method then we can help you. – eyllanesc Mar 26 '20 at 16:10
  • @eyllanesc Thank you very much! I solved the problem and edited the second case. Would you advice more? if you have any more advice – jin1ib Mar 27 '20 at 02:47
  • As I pointed out: It seemed to me that your implementation was incorrect so it was not necessary to publish the same answer, in general it is recommended that if you point out that you have used the solution of another question and it does not work then you should show the code since perhaps you have not implemented correctly. – eyllanesc Mar 27 '20 at 02:49
  • change to `image = QImage(self._photo.boundingRect().size().toSize(), QImage.Format_ARGB32_Premultiplied)` – eyllanesc Mar 27 '20 at 02:50
  • and `self._scene.render(painter, QRectF(image.rect()), self._photo.boundingRect())` – eyllanesc Mar 27 '20 at 02:51
  • They are only minimal questions not to use the conversion to "int" but in general your solution is good. – eyllanesc Mar 27 '20 at 02:52

0 Answers0