如何裁剪图像并保存?

Posted

技术标签:

【中文标题】如何裁剪图像并保存?【英文标题】:How to crop a image and save? 【发布时间】:2014-09-11 19:11:57 【问题描述】:

我在QHBoxLayout 中打开了一张图片。我需要裁剪打开的图像并保存裁剪的图像。我如何在 PySide 中做到这一点?

import sys
from PySide import QtGui, QtCore

class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):      

        hbox = QtGui.QHBoxLayout(self)
        pixmap = QtGui.QPixmap("re.png")

        lbl = QtGui.QLabel(self)
        lbl.setPixmap(pixmap)


        self.rect = QtCore.QRect()


        hbox.addWidget(lbl)
        self.setLayout(hbox)

        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('Open Image')
        self.show()   
        # Tried here to implement Qpen      
        #self.painter = QtGui.QPainter(self)    
        #self.painter.setPen(QtGui.QPen(QtCore.Qt.black, 1, QtCore.Qt.SolidLine));
        #self.painter.drawRect(self.rect);
def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

【问题讨论】:

在 QHBoxLayout 中显示它对裁剪是否重要?您是否还想通过 QRubberBand 指定裁剪区域? 不,在 QHBoxLayout 中显示裁剪并不重要。我只是想在布局中显示图像并裁剪并保存。如何使用`QRubberBand`? 如果它比原则上不重要,您不需要显示您显示的任何代码。这将使问题更短,更容易理解和更好。但是,如果您希望用户选择裁剪区域,那么我建议您使用 QRubberBand。我没有找到任何好的例子。但是文档应该已经有所帮助或在这里提出问题。 【参考方案1】:

我建议使用QtGui.QRubberBand 类来选择要裁剪的图像区域。 (PySide 也实现了与 PyQt 相同的功能)

首先,实现方法mouseMoveEvent (self, QMouseEvent)mouseReleaseEvent (self, QMouseEvent)mousePressEvent (self, QMouseEvent)(更多信息请阅读QtGui.QRubberBand 类参考)。

接下来,使用QRect QWidget.geometry (self)获取QtGui.QRubberBand的最后一个几何图形以裁剪图像。

最后,使用QPixmap QPixmap.copy (self, QRect rect = QRect()) 通过从裁剪区域放置几何图形来裁剪图像。并使用bool QPixmap.save (self, QString fileName, str format = None, int quality = -1)保存图像。

示例;

import sys
from PyQt4 import QtGui, QtCore

class QExampleLabel (QtGui.QLabel):
    def __init__(self, parentQWidget = None):
        super(QExampleLabel, self).__init__(parentQWidget)
        self.initUI()

    def initUI (self):
        self.setPixmap(QtGui.QPixmap('input.png'))

    def mousePressEvent (self, eventQMouseEvent):
        self.originQPoint = eventQMouseEvent.pos()
        self.currentQRubberBand = QtGui.QRubberBand(QtGui.QRubberBand.Rectangle, self)
        self.currentQRubberBand.setGeometry(QtCore.QRect(self.originQPoint, QtCore.QSize()))
        self.currentQRubberBand.show()

    def mouseMoveEvent (self, eventQMouseEvent):
        self.currentQRubberBand.setGeometry(QtCore.QRect(self.originQPoint, eventQMouseEvent.pos()).normalized())

    def mouseReleaseEvent (self, eventQMouseEvent):
        self.currentQRubberBand.hide()
        currentQRect = self.currentQRubberBand.geometry()
        self.currentQRubberBand.deleteLater()
        cropQPixmap = self.pixmap().copy(currentQRect)
        cropQPixmap.save('output.png')

if __name__ == '__main__':
    myQApplication = QtGui.QApplication(sys.argv)
    myQExampleLabel = QExampleLabel()
    myQExampleLabel.show()
    sys.exit(myQApplication.exec_())

【讨论】:

【参考方案2】:

我会使用 QImage 的 copy 方法:

im2 = im.copy(self.rect)
im2.save(...)

【讨论】:

【参考方案3】:
import sys
from PyQt5 import QtGui, QtCore,QtWidgets
from PyQt5.QtWidgets import QRubberBand, QLabel, QApplication, QWidget
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import QRect


class QExampleLabel (QLabel):
    def __init__(self, parentQWidget = None):
        super(QExampleLabel, self).__init__(parentQWidget)
        self.initUI()

    def initUI (self):
        self.setPixmap(QPixmap('input.png'))

    def mousePressEvent (self, eventQMouseEvent):
        self.originQPoint = eventQMouseEvent.pos()
        self.currentQRubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.currentQRubberBand.setGeometry(QRect(self.originQPoint, QtCore.QSize()))
        self.currentQRubberBand.show()

    def mouseMoveEvent (self, eventQMouseEvent):
        self.currentQRubberBand.setGeometry(QRect(self.originQPoint, eventQMouseEvent.pos()).normalized())

    def mouseReleaseEvent (self, eventQMouseEvent):
        self.currentQRubberBand.hide()
        currentQRect = self.currentQRubberBand.geometry()
        self.currentQRubberBand.deleteLater()
        cropQPixmap = self.pixmap().copy(currentQRect)
        cropQPixmap.save('output.png')

if __name__ == '__main__':
    myQApplication = QApplication(sys.argv)
    myQExampleLabel = QExampleLabel()
    myQExampleLabel.show()
    sys.exit(myQApplication.exec_())

【讨论】:

这个答案没有解释它为什么起作用,如何从中学习?

以上是关于如何裁剪图像并保存?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Swift选择图像的一部分,裁剪并保存?

裁剪图像并保存到 sdcard (Android) 中的特定文件夹?

有没有很好的例子说明如何在 selenium webdriver C# 中截取屏幕截图,然后裁剪并保存图像?

如何使用 PHP 将裁剪后的图像保存到带有 Jcrop 的目录

我只想将裁剪后的图像保存到图库中。但它保存了原始的完整图像。如何只保存裁剪的图像?

在 imagebox 控件中裁剪图像并保存