我有一个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;
}
}
}
答案 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);
}