【问题标题】:Replace a part of a QPixMap with a smaller QPixMap用更小的 QPixMap 替换 QPixMap 的一部分
【发布时间】:2016-11-21 15:25:36
【问题描述】:

我是 Qt 和 Qt 图形 API 的新手。

我有一个较大的QPixMap 和一个较小的QPixMap。我需要将较大的部分(QRect)替换为较小的部分。

我应该如何做到这一点?

谢谢。

更新

QPainter::drawPixmap() 不会更新 pImage->p_PixMap 所代表的图像。

代码

class GraphicImage : public QObject,
    public QGraphicsPixmapItem
{
    Q_OBJECT

public:
    GraphicImage(QPixmap* oImage,GraphiItemCtrl* pParent);
    virtual ~GraphicImage(void);
    QPixmap* p_PixMap;
};
- - - - 
GraphicImage::GraphicImage(QPixmap* oImage,GraphiItemCtrl* pParent)
    :QGraphicsPixmapItem(*oImage), p_Parent(pParent)
{
    p_PixMap = oImage;
}
- - - - 
void GraphiItemCtrl::SetImagePortion( QString sFileName, QRect rect, QPixmap pChildPixMap )
{
    GraphicImage* pImage = map_CurrentImages[sFileName];

    if ( !pImage )
        return;

    pChildPixMap.save("test.jpg");
    QPixmap* pMap = pImage->p_PixMap;
    QPainter pPainter(pMap);

    pPainter.drawPixmap(rect, pChildPixMap);
    qDebug() << rect.topLeft();
}

pChildPixMap.save("test.jpg"); 可以毫无问题地保存图像的所需部分。

注意pImage 继承自 QObject 和 QGraphicsPixmapItem。 pMap 不是 NULL

【问题讨论】:

标签: c++ qt


【解决方案1】:

你要找的功能是:

void QPainter::drawPixmap(const QRect &rectangle, const QPixmap &pixmap)

它将pixmap 绘制到画家目标的rectangle 部分。

您可能还想使用这个:

void QPainter::drawPixmap(const QRect &target, const QPixmap &pixmap, const QRect &source)

这会将源的一部分绘制到目标的一部分中。

在这两种情况下,如果尺寸不匹配,图像将被缩放,所以如果你得到的结果很差,你还需要调整缩放方法。

正如this answer 中所述,设置setRenderHint(QPainter::SmoothPixmapTransform); 本身似乎不会产生最佳结果。如果您想要最好的质量,您需要手动scale() 像素图然后绘制它,这比在绘制时动态缩放它产生更好的结果。

【讨论】:

  • 那我应该如何提取输出QPixMap
  • “提取”是什么意思? “输出”只是您的画家设置要在其上绘制的像素图。
  • 那么,目标 PixMap 会自动更新吗?我会试试这个然后回来。
  • 更新了问题。
  • @PraneethNilangaPeiris - p_PixMap 是什么?看起来您正在向画家传递一个无效的指针。
【解决方案2】:

快速伪代码:

QPainter painter(pixmap1);
painter.drawPixmap(QRect, pixmap2);

查看文档here

【讨论】:

  • 谢谢,我会试试这个然后回来。
  • 那我应该如何提取输出QPixMap
  • @PraneethNilangaPeiris 您将调用drawPixmap 的像素图将被绘制到
  • @MarcoA。这概括得太笼统了:您有 option利用 QObjects 之间的父子关系来进行内存管理。它是真正且完全可选的。对象可以按值保存子对象,然后 C++ 语义确保子对象在需要时被销毁。例如。 class Foo : public QWidget { QLabel child1{"Hello", this}; QLabel child2{"World", this}; ... }; - 标签将在父级之前消失,Qt 根本不参与其中。如果孩子的一生是父母的一生,你就应该珍惜他们!
  • @MarcoA。请注意广义的“最 Qt 内存管理”和“QObjects 之间的父子关系”之间的区别:并非所有内容都是QObject。另请注意,利用它是可选的:您可以,但您不必这样做,如果父子生命周期相同并且您是父类的作者,则不应该这样做。
【解决方案3】:

您需要在目标像素图上使用画家在给定的目标矩形中绘制源像素图:

void draw(QPixmap &dst, const QRect &dstRect, const QPixmap &src) {
  QPainter(dst).drawPixmap(dstRect, src); 
}

如果您在一个目的地上绘制多个这样的像素图,您应该保留画家 - 在循环中一遍又一遍地构建新画家会很浪费:

struct Replacement {
  QRect dstRect;
  QPixmap source;
};

void draw(QPixmap &dst, const QList<Replacement> &replacements) {
  QPainter painter{dst};
  for (auto & r : replacements)
    painter.drawPixmap(r.dstRect, r.source);
}

【讨论】:

    猜你喜欢
    • 2019-04-01
    • 2013-04-18
    • 2015-10-14
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多