1

同じ QPixmap をより大きな QPixmap に何度も描画する必要があるため、いくつかのコードを最適化しようとしています。私自身のメソッドで値によって QPixmap を渡すと、呼び出すたびにコピーが作成されるため、QPixmap へのポインターを操作することで時間を短縮できると考えました。しかし、私の仕事は無駄だったようです。QPainter::drawPixmap(..., const QPixmap&, ...) を呼び出すとそのコピーが作成されるためだと思います。

QPixmap *pixmap = new QPixmap(10,10);
painter.drawPixmap(0,0, *pixmap);

この例ではコピーが作成されていますか?

もしそうなら、どうすれば多くの画像を別の画像に描画するのを最適化できますか?

私はすでにこの Q/A をここで読みました:ポインターを逆参照するとコピーが作成されますか? しかし、私の特定のケースに対する明確な答えは私にはわかりません。

4

2 に答える 2

4

いいえ。関数は への参照をdrawPixmap取るため、コピーは作成されません。QPainter メンバー関数のプロトタイプは次のとおりです。constpixmap

  void  drawPixmap ( int x, int y, const QPixmap & pixmap )
于 2013-03-05T03:18:25.560 に答える
0

QPixmapクラスリファレンスによると:

QPixmap クラスは暗黙的なデータ共有を使用するため、QPixmap オブジェクトは値で渡すことができます。詳細については、暗黙的なデータ共有のドキュメントを参照してください。

QPixmap の実装:

QPixmap::QPixmap(const QPixmap &pixmap)
    : QPaintDevice()
{
    if (!qt_pixmap_thread_test()) {
        init(0, 0, QPixmapData::PixmapType);
        return;
    }
    if (pixmap.paintingActive()) {                // make a deep copy
        operator=(pixmap.copy());
    } else {
        data = pixmap.data;
    }
}

ピックスマップがアクティブにペイントされている場合にのみ、ディープ コピーが必要になります。それ以外の場合、新しいピックスマップは元のデータ ポインターをコピーするだけで済みます。

const参照とポインタの違いについて:

QPixmap largeMap(1000, 1000);
QPainter p(&largeMap);

int count = 100000;
qint64 time1, time2;
QPixmap *pSmallMap = new QPixmap("e:/test.png");
QPixmap smallMap = QPixmap("e:/test.png");

time1 =  QDateTime::currentMSecsSinceEpoch();
for (int i = 0; i < count; ++i) {
    p.drawPixmap(0, 0, *pSmallMap);
}
time2 =  QDateTime::currentMSecsSinceEpoch();;
qDebug("def time = %d\n", time2 - time1);

time1 =  QDateTime::currentMSecsSinceEpoch();
for (int i = 0; i < count; ++i) {
    p.drawPixmap(0, 0, smallMap);
}
time2 =  QDateTime::currentMSecsSinceEpoch();;
qDebug("normal time = %d\n", time2 - time1);

Visual Studio 2010デバッグ構成でコンパイルすると、次のアセンブリが生成されます。

    28:         p.drawPixmap(0, 0, *pSmallMap);
003B1647 8B 55 C4             mov         edx,dword ptr [ebp-3Ch]  //the pixmap pointer
003B164A 52                   push        edx  
003B164B 6A 00                push        0  //x
003B164D 6A 00                push        0  //y
003B164F 8D 4D F0             lea         ecx,[ebp-10h]  //the qpainter pointer
003B1652 FF 15 9C D7 3B 00    call        dword ptr [__imp_QPainter::drawPixmap (3BD79Ch)]

    35:         p.drawPixmap(0, 0, smallMap);
003B16A8 8D 4D E0             lea         ecx,[ebp-20h]  //the pixmap pointer
003B16AB 51                   push        ecx            
003B16AC 6A 00                push        0              //x
003B16AE 6A 00                push        0              //y
003B16B0 8D 4D F0             lea         ecx,[ebp-10h]  //the qpainter pointer
003B16B3 FF 15 9C D7 3B 00    call        dword ptr [__imp_QPainter::drawPixmap (3BD79Ch)]  

コンパイラは同じアセンブリ コードを生成するため、この 2 つに違いはありません。ポインタを drawPixmap 関数に渡します。

QDateTime::currentMSecsSinceEpoch() は、私のボックスでほぼ同じ結果を示しています。

于 2013-03-05T03:20:36.167 に答える