【初心者向け】Qt Widgetsで画像エフェクトを使いこなす!QGraphicsEffect::sourcePixmap()の基礎知識


QGraphicsEffect::sourcePixmap() は、Qt Widgetsライブラリで提供されるグラフィック効果クラス QGraphicsEffect のメンバー関数です。この関数は、効果が適用される元の画像データを取得するために使用されます。つまり、効果がどのように画像を変形または操作しているかを理解したい場合に役立ちます。

機能

sourcePixmap() 関数は、以下の引数を取ります。

  • mode: 元画像データのパディングモードを指定します。デフォルトは PadToEffectiveBoundingRect です。
  • offset: 元画像データのオフセットを格納するポインタです。この引数は省略可能です。
  • system: 元画像データの座標系を指定します。デフォルトは Qt::LogicalCoordinates です。

この関数は、QPixmap オブジェクトを返します。このオブジェクトには、効果が適用される前の元の画像データが含まれています。

次のコードは、QGraphicsBlurEffect 効果を使用して画像をぼかすと、効果が適用される前の元の画像を取得する方法を示しています。

QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap("image.png"));
QGraphicsBlurEffect *effect = new QGraphicsBlurEffect;
effect->setBlurRadius(5.0);
item->setGraphicsEffect(effect);

QPixmap sourcePixmap = effect->sourcePixmap();

このコードでは、まず QGraphicsPixmapItem オブジェクトを作成し、"image.png" 画像をロードします。次に、QGraphicsBlurEffect オブジェクトを作成し、ぼかし半径を 5.0 に設定します。最後に、効果を QGraphicsPixmapItem オブジェクトに設定します。

sourcePixmap() 関数を呼び出すことで、効果が適用される前の元の画像データを取得できます。このデータは QPixmap オブジェクトに格納され、後で処理に使用できます。

  • 効果が適用される元の画像データが常に利用できるとは限りません。たとえば、効果がリアルタイムでレンダリングされる場合、元の画像データへのアクセスはできない場合があります。
  • sourcePixmap() 関数は、効果が適用される元の画像データのみを取得します。効果がどのように画像を変形または操作しているかについては、draw() メンバー関数を実装する必要があります。


#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QGraphicsBlurEffect>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;
    QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap("image.png"));
    scene.addItem(item);

    QGraphicsBlurEffect *effect = new QGraphicsBlurEffect;
    effect->setBlurRadius(5.0);
    item->setGraphicsEffect(effect);

    QPixmap sourcePixmap = effect->sourcePixmap();

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

例2:ドロップシャドウ効果

この例では、QGraphicsDropShadowEffect 効果を使用して画像にドロップシャドウを追加し、効果が適用される前の元の画像を取得する方法を示します。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QGraphicsDropShadowEffect>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QGraphicsScene scene;
    QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap("image.png"));
    scene.addItem(item);

    QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect;
    effect->setBlurRadius(10.0);
    effect->setOffset(5, 5);
    effect->setColor(QColor(100, 100, 100));
    item->setGraphicsEffect(effect);

    QPixmap sourcePixmap = effect->sourcePixmap();

    QGraphicsView view(&scene);
    view.show();

    return app.exec();
}

説明

これらの例では、まず QGraphicsScene オブジェクトを作成し、"image.png" 画像をロードする QGraphicsPixmapItem オブジェクトを追加します。次に、効果を作成し、効果のパラメータを設定します。最後に、効果を QGraphicsPixmapItem オブジェクトに設定します。



  • 効果が複雑な場合、sourcePixmap() 関数は元の画像データではなく、効果がレンダリングした画像を返す場合があります。
  • 効果がリアルタイムでレンダリングされる場合、元の画像データへのアクセスができない場合があります。

このような場合、QGraphicsEffect::sourcePixmap() 関数の代替方法が必要になります。

代替方法

以下の代替方法を検討することができます。

効果の draw() メンバー関数を実装する

効果クラスは、draw() メンバー関数を提供しています。この関数は、効果がどのように画像を変形または操作しているかを理解するための最も直接的な方法です。

draw() メンバー関数は、以下の引数を取ります。

  • device: 効果が描画されるデバイスを指します。
  • rect: 効果が適用される矩形を格納します。
  • painter: 効果が描画されるペインターオブジェクトを指します。

この関数は、QPainter オブジェクトを使用して元の画像データを直接描画する必要があります。

次のコードは、QGraphicsBlurEffect 効果をシミュレートする draw() メンバー関数の実装例です。

class MyBlurEffect : public QGraphicsEffect
{
public:
    MyBlurEffect() = default;

    void draw(QPainter *painter, const QRectF &rect, const QRectF &deviceRect) override {
        QPixmap sourcePixmap = sourcePixmap(Qt::LogicalCoordinates);
        if (!sourcePixmap.isNull()) {
            painter->save();
            painter->translate(rect.topLeft());
            painter->scale(deviceRect.width() / rect.width(), deviceRect.height() / rect.height());
            painter->setRenderHint(QPainter::Antialiasing);
            painter->blur(rect, blurRadius);
            painter->drawPixmap(QRect(0, 0, rect.width(), rect.height()), sourcePixmap);
            painter->restore();
        }
    }

private:
    qreal blurRadius = 5.0;
};

効果が適用される前に元の画像データを保存する

効果を適用する前に、元の画像データを保存することができます。この方法は、効果がリアルタイムでレンダリングされない場合にのみ有効です。

次のコードは、効果を適用する前に元の画像データを保存する方法を示しています。

QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap("image.png"));
QPixmap sourcePixmap = item->pixmap();

QGraphicsBlurEffect *effect = new QGraphicsBlurEffect;
effect->setBlurRadius(5.0);
item->setGraphicsEffect(effect);

効果がレンダリングした画像をキャプチャする

効果がレンダリングした画像をキャプチャすることができます。この方法は、効果が複雑な場合にのみ有効です。

次のコードは、効果がレンダリングした画像をキャプチャする方法を示しています。

QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap("image.png"));
QGraphicsBlurEffect *effect = new QGraphicsBlurEffect;
effect->setBlurRadius(5.0);
item->setGraphicsEffect(effect);

QPixmap renderedPixmap = item->scene()->grabWindowPixmap(item->boundingRect());