在 Qt 中使用 QRubberBand 裁剪图像

Posted

技术标签:

【中文标题】在 Qt 中使用 QRubberBand 裁剪图像【英文标题】:Using QRubberBand to crop image in Qt 【发布时间】:2012-08-09 11:03:57 【问题描述】:

我希望能够使用橡皮筋选择图像的一个区域,然后删除橡皮筋之外的图像部分并显示新图像。但是,当我目前这样做时,它不会裁剪正确的区域并给我错误的图像。

#include "mainresizewindow.h"
#include "ui_mainresizewindow.h"

QString fileName;

MainResizeWindow::MainResizeWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainResizeWindow)

    ui->setupUi(this);
    ui->imageLabel->setScaledContents(true);
    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(open()));


MainResizeWindow::~MainResizeWindow()

    delete ui;


void MainResizeWindow::open()

    fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::currentPath());


    if (!fileName.isEmpty()) 
        QImage image(fileName);

        if (image.isNull()) 
            QMessageBox::information(this, tr("Image Viewer"),
                                 tr("Cannot load %1.").arg(fileName));
            return;
        

    ui->imageLabel->setPixmap(QPixmap::fromImage(image));
    ui->imageLabel->repaint();
    


void MainResizeWindow::mousePressEvent(QMouseEvent *event)

    if(ui->imageLabel->underMouse())
        myPoint = event->pos();
        rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
        rubberBand->show();
    


void MainResizeWindow::mouseMoveEvent(QMouseEvent *event)

    rubberBand->setGeometry(QRect(myPoint, event->pos()).normalized());


void MainResizeWindow::mouseReleaseEvent(QMouseEvent *event)

    QRect myRect(myPoint, event->pos());

    rubberBand->hide();

    QPixmap OriginalPix(*ui->imageLabel->pixmap());

    QImage newImage;
    newImage = OriginalPix.toImage();

    QImage copyImage;
    copyImage = copyImage.copy(myRect);

    ui->imageLabel->setPixmap(QPixmap::fromImage(copyImage));
    ui->imageLabel->repaint();

任何帮助表示赞赏。

【问题讨论】:

myRect 将位于 MainResizeWindow 坐标中,而不是 copyImage 坐标中。检查坐标值。 【参考方案1】:

这里有两个问题 - 矩形相对于图像的位置以及图像(可能)在标签中缩放的事实。

职位问题:

QRect myRect(myPoint, event->pos());

您或许应该将其更改为:

QPoint a = mapToGlobal(myPoint);
QPoint b = event->globalPos();

a = ui->imageLabel->mapFromGlobal(a);
b = ui->imageLabel->mapFromGlobal(b);

然后,标签可能正在缩放图像,因为您使用了 setScaledContents()。因此,您需要计算出未缩放图像上的实际坐标。可能是这样的(未经测试/编译):

QPixmap OriginalPix(*ui->imageLabel->pixmap());
double sx = ui->imageLabel->rect().width();
double sy = ui->imageLabel->rect().height();
sx = OriginalPix.width() / sx;
sy = OriginalPix.height() / sy;
a.x = int(a.x * sx);
b.x = int(b.x * sx);
a.y = int(a.y * sy);
b.y = int(b.y * sy);

QRect myRect(a, b);
...

【讨论】:

以上是关于在 Qt 中使用 QRubberBand 裁剪图像的主要内容,如果未能解决你的问题,请参考以下文章

QRubberBand,如何在上面画画

我想裁剪图像并输入在图像中查看。如何使用这种类型的裁剪从相机裁剪图像?

QGraphicsScene 中 Qrubberband 的错误渲染

在android中使用人脸检测裁剪图像

GUI学习之二十二——QRubberBand学习总结

使用非矩形形状在 flex 中裁剪图像