【问题标题】:How to rotate a QPixmap without changing size如何在不改变大小的情况下旋转 QPixmap
【发布时间】:2017-12-02 20:13:59
【问题描述】:

如何在不改变大小的情况下旋转 QPixmap 我使用此代码,但是当我旋转图像时,它会改变图像的大小。

头文件

#ifndef CUSTOMDIAL_H
#define CUSTOMDIAL_H
#include <QDial>
class CustomDial : public QDial
{
Q_OBJECT
public:
CustomDial(QWidget * parent = nullptr);
private:
virtual void paintEvent(QPaintEvent*) override;
};
#endif

CPP 文件

#include "Customdial.h"
#include <QGraphicsPixmapItem>
#include <QPainter>
#include <QColor>
#include <QPixmap>
 CustomDial::CustomDial(QWidget* parent)
                    : QDial(parent)
 {
// Default range
QDial::setRange(0,100);
}   
void CustomDial::paintEvent(QPaintEvent*)
{
int a = QDial::sliderPosition();
QPainter painter(this);
//load pixmap
QPixmap pix(":/img/img/knob.png");
//rotate pixmap
QMatrix rm;
        rm.rotate(a);
        pix = pix.transformed(rm);
//draw pixmap
painter.drawPixmap(QPointF(0,0),
                    pix.scaled(QDial::height(),
                    QDial::height(),
                    Qt::KeepAspectRatio),
                    pix.rect().adjusted(1, 1, -1000, -1000) );
}

如何在不改变大小的情况下旋转 QPixmap 我使用此代码,但是当我旋转图像时,它会改变图像头文件的大小

【问题讨论】:

  • 什么意思,解释清楚,你可以放一张你得到什么和你想得到什么的图像。
  • 我刚刚为 QDial 创建了一个自定义类,以支持样式表以添加背景图像现在我的问题是,当您使用此代码在拨号器中旋转图像时,它会更改图像的大小,是否还有另一个旋转 Qpixmap 的方法?
  • 显示您的代码,测试您的代码并查看如何修复它。
  • 这是我的代码,我使用 png 旋转按钮获取资源

标签: qt qpixmap


【解决方案1】:

关于您的问题,您可以使用 QPixmap::copy() 来提取所需大小的中心部分:

//load pixmap
QPixmap pix(":/images/pixmap.png");
//rotate pixmap
QMatrix rm;
rm.rotate(a);
int pxw = pix.width(), pxh = pix.height();
pix = pix.transformed(rm);
pix = pix.copy((pix.width() - pxw)/2, (pix.height() - pxh)/2, pxw, pxh);

但这会效率低下(另请参阅QPixmap::transformed() 的注释)。我更喜欢直接使用 QPainter 绘制而不创建中间像素图,尤其是因为您已经拥有它:

qreal scale = qMin(width(), height()) / qMax(pix.width(), pix.height());
QPointF center(width() / 2., height() / 2.); // widget center
// uncomment to trade performance for quality
//  painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.translate(center);
painter.rotate(degrees);
painter.scale(scale, scale);
painter.drawPixmap(-pix.rect().center(), pix);

还可以考虑在您的小部件初始化时加载 QPixmap 并将其存储,而不是在 paintEvent 中执行(再次为效率起见)。

QPixmap::transformed() 增加旋转尺寸的原因是为了获得包括边缘在内的整个图像,因为您总是可以从较大的图像中提取较小的图像,但反之则不行。您可能有一张圆形图片,但对于矩形,它立即显而易见。

【讨论】:

    【解决方案2】:

    Qdial计算背景圆的方法是这样的

    int width = option.rect.width();
    int height = option.rect.height();
    qreal r2 = qMin(width, height) / 2;
    r2 -= r2/50;
    const qreal d_ = r2 / 6;
    const qreal dx = option.rect.x() + d_ + (width - 2 * r2) / 2 + 1;
    const qreal dy = option.rect.y() + d_ + (height - 2 * r2) / 2 + 1;
    QRectF br = QRectF(dx + 0.5, dy + 0.5,
                   int(r2 * 2 - 2 * d_ - 2),
                   int(r2 * 2 - 2 * d_ - 2));
    

    所以QRect br 是背景圆的矩形。然后只需使用这些坐标添加 Pixmap 资源文件

     int w=option.rect.width()/2;
     int h=option.rect.height()/2;
     painter.translate(w,h);
     painter.rotate(a);
    
     //draw pixmap
     painter.drawPixmap(-br.width()/2,
                        -br.height()/2,
                             pix.scaled(br.width(),br.height(),Qt::KeepAspectRatio));
    

    您会在表盘内获得完美的可调整大小和可旋转的图像

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-30
      相关资源
      最近更新 更多