在Qt中的鼠标移动事件上调整/缩放矩形形状的png图像

时间:2014-05-01 08:16:24

标签: qt png qgraphicsitem

我有一个QGraphicPixmapItem,它包含场景中的png图像。

图像本身是一个矩形图像。我的要求是,当我在鼠标移动事件上调整矩形图像的大小时,我应该能够调整图像大小/缩放。  我可以通过拖动矩形图像的任何一侧来调整矩形的大小。

问题在于,我能够通过拖动任何一侧来调整矩形图像的大小,但原始图像却被无法识别而扭曲。图像基本上 在连续调整大小(扩展/减小宽度或高度)时变成一团实体。 如何在不损坏原始图像的情况下实现Qt中图像的大小调整/缩放?我所经历的不是像素化,而是更糟糕。

下面的代码是QGraphicsPixmapItem的mouseMoveEvent()的快照,用于通过拖动矩形图像的右/左侧来调整矩形的大小。

 void PersonSizeGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        const QPointF event_pos = event->pos();
        const QPointF event_scene_pos = event->scenePos();

        QPixmap current_pixmap = this->pixmap();
        QImage current_image = current_pixmap.toImage();
        QRect current_image_rect = current_image.rect();

        QPoint current_top_left = current_image_rect.topLeft();
        QPoint current_bottom_right = current_image_rect.bottomRight();

        if((event->scenePos().x() > this->scene()->width()) || (event->scenePos().y() > this->scene()->height())
            || (event->scenePos().x() < 0) || (event->scenePos().y() < 0) )
        {
            return;
        }

        if( this->cursor().shape() == Qt::SizeHorCursor )
        {
            if(rect_right_condition)
            {
                        new_rect = QRect( current_top_left, QPoint( event->pos().x(), current_bottom_right.y()) );


                scaled_pixmap = QPixmap::fromImage(current_image.scaled(QSize(new_rect.width(),new_rect.height()),Qt::IgnoreAspectRatio,Qt::FastTransformation));

                setPixmap(scaled_pixmap);

     }

            if(rect_left_condition)
            {
                            new_rect = QRect( QPoint(event_pos.x(), 0), current_bottom_right );

    scaled_pixmap = QPixmap::fromImage(current_image.scaled(QSize(new_rect.width(),new_rect.height()),Qt::IgnoreAspectRatio,Qt::FastTransformation));
                setPixmap(scaled_pixmap);
                QPoint new_top_left = new_rect.topLeft();
                QPointF mapped_topLeft = mapToParent(QPointF(new_top_left.x(),new_top_left.y()));
                this->setPos(mapped_topLeft);
                rect_resize_occurred = true;


            }

        }
    }

2 个答案:

答案 0 :(得分:1)

  

在连续调整大小(扩展/减小宽度或高度)时,图像基本上会变成一团实体。

这很正常。你需要做的是改变你想要的效果的方法。而不是不断更改相同的图像,而是从您期望用户需要的最大尺寸的源图像开始。此图片不会被更改。

在mouseMove函数中,更新成员变量以存储您显示的图像的大小。

然后,在PersonSizeGraphicsItem的paint函数中,使用drawImage指定源图像,使用目标rect来绘制mouseMoveEvent中更新大小的图像: -

void QPainter::drawImage(const QRectF & rectangle, const QImage & image);

因此,通过将源图像保持为原始大小,每次连续调整大小时,您不会越来越多地扭曲它。

class PersonSizeGraphicsItem : public QGraphicsItem
{
    public:
        PersonSizeGraphicsItem(QGraphicsItem* parent);

    protected:
        void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
        void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0)

    private:
        QRectF m_imageRect;
        QImage m_image;
};

void PersonSizeGraphicsItem::mouseMoveEvent()
{
   // Update the image rect here
}

void PersonSizeGraphicsItem::paint(QPainter * painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->drawImage(m_imageRect, m_image);
}

答案 1 :(得分:0)

基于Merlin069的重新实现的代码答案:

PersonSizeGraphicsItem::PersonSizeGraphicsItem(const QPixmap &pixmap, QGraphicsScene *scene)
    :QGraphicsPixmapItem(pixmap, 0, scene)
{
    this->setFlag(QGraphicsItem::ItemIsMovable, true);
    this->setFlag(QGraphicsItem::ItemIsSelectable, true);
    this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
    this->setFlag(QGraphicsItem::ItemIsFocusable, true);
    this->setFocus(Qt::MouseFocusReason);
    this->setAcceptHoverEvents(true);
    //this->setScale(0.5);

    rect_left_condition = false;
    rect_right_condition = false;
    rect_top_condition = false;
    rect_bottom_condition = false;
    rect_resize_occurred = false;
    image_rect = QRect();
    image_rect =  this->pixmap().toImage().rect();
}

void PersonSizeGraphicsItem::setSourceImage(const QImage& source_image)
{
    this->source_image =  source_image;
}


void PersonSizeGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    const QPointF event_pos = event->pos();
    const QPointF event_scene_pos = event->scenePos();

    QPoint current_top_left = image_rect.topLeft();
    QPoint current_bottom_right = image_rect.bottomRight();

    if((event->scenePos().x() > this->scene()->width()) || (event->scenePos().y() > this->scene()->height())
        || (event->scenePos().x() < 0) || (event->scenePos().y() < 0) )
    {
        return;
    }

    if( this->cursor().shape() == Qt::SizeHorCursor )
    {
        if(rect_right_condition)
        {

        image_rect = QRect( current_top_left, QPoint( event->pos().x(), current_bottom_right.y()) );

        }

        if(rect_left_condition)
        {

            image_rect = QRect( QPoint(event_pos.x(), 0), current_bottom_right);

            QPoint new_top_left = image_rect.topLeft();
            QPointF mapped_topLeft = mapToParent(QPointF(new_top_left.x(),new_top_left.y()));
            this->setPos(mapped_topLeft);
            rect_resize_occurred = true;

            //qDebug() << "new rectangle top left**:" << this->pixmap().rect().topLeft();
        }

    }

    if( this->cursor().shape() == Qt::SizeVerCursor )
    {
        if(rect_bottom_condition)
        {

            image_rect = QRect(current_top_left, QPoint(current_bottom_right.x(), event->pos().y()));


    }

        if(rect_top_condition)
        {
            image_rect = QRect(QPoint(0, event_pos.y()), current_bottom_right);

                        QPoint new_top_left = image_rect.topLeft();
            QPointF mapped_topLeft = mapToParent(QPointF(new_top_left.x(),new_top_left.y()));
            this->setPos(mapped_topLeft);


        }
    }

    this->update();

}

void PersonSizeGraphicsItem::paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->drawImage(image_rect, source_image);
}