2012-11-26 11 views
5

私はC++/Qtの新機能で、Visual Studio C++とQt(4.8.3)でアプリケーションを作成しようとしています。アプリケーションはQGraphicsViewを使用して画像を表示するため、ピクセルレベルで画像を変更する必要があります。大きなQImageの問題

基本的なコードは、(簡略化)である。

QImage* img = new QImage(img_width,img_height,QImage::Format_RGB32); 
while(do_some_stuff) { 
    img->setPixel(x,y,color); 
} 
QGraphicsPixmapItem* pm = new QGraphicsPixmapItem(QPixmap::fromImage(*img)); 
QGraphicsScene* sc = new QGraphicsScene; 
sc->setSceneRect(0,0,img->width(),img->height()); 
sc->addItem(pm); 
ui.graphicsView->setScene(sc); 

これは約12000x6000画素までの画像に適しています。奇妙なことは、このサイズを超えて発生します。たとえば、img_width=16000img_height=8000と設定すると、img = new QImage(...)という行はヌルイメージを返します。イメージデータは約512,000,000バイトである必要があります。したがって、32ビットシステムであっても、それは大きすぎてはなりません。また、私のマシン(Win 7 64ビット、8 GB RAM)はデータを保持できる必要があります。私も、このバージョン試してみた

:最初は

uchar* imgbuf = (uchar*) malloc(img_width*img_height*4); 
QImage* img = new QImage(imgbuf,img_width,img_height,QImage::Format_RGB32); 

を、これは動作します。 imgポインタが有効で、たとえばimg->width()を呼び出すと、正しい画像幅が返されます(画像ポインタがnullの場合は0ではなく)。 しかし、私がimg->setPixel()と呼ぶとすぐに、ポインタはヌルになり、img->width()は0を返します。

どうしたのですか?または、ピクセルレベルで大きな画像を変更するより良い方法はありますか?

よろしく、 デビッド

+0

割り当てが実際に動作しているかどうかを確認するには、まずmallocされたメモリを手動でゼロにします。 –

+0

これを見てみましょう:[QtプロジェクトWiki:大きな画像を読み込む](http://qt-project.org/wiki/LoadingLargeImages) – dschulz

+0

32ビットWindowsアプリケーションでは、デフォルトの最大割り当てが結果として得られますアドレススペースの断片化は、/ LARGEADDRESSAWAREリンカフラグを使用せずに、アプリケーションが使用するdllをリベースすることなく、断片化を軽減するために約1.2GB(2GBのアプリケーションアドレス空間)になります。 – drescherjm

答えて

1

第2のアプローチは適切な方法です。あなたがそれを持っている問題は、setPixel()と呼ぶときに、QImageはあなたが提供した外部バッファのコピーを作り、そのためにメモリが不足しています。

付属のバッファーで直接ピクセル値を変更してみてください。 scanLine()を使用すると、行のバッファへのポインタを取得できます。本当に遅いので、私はsetPixel()を使用しません。

+0

よろしくお願いいたします。 scanLine()を見ていきます。 –

4

QImageの32768x32768 PX画像(短符号付き)の最大値をサポートします。これは、幅*高さ*色深度< INT_MAX(40億) - > 32768 * 32768 * 4 = 40億という条件から得られます。第2の条件はもちろん、mallocが要求されたメモリを割り当てることができることです。

大きな画像が本当に必要な場合は、別のラッパーを使用するか、複数のQImageに分割する必要があります。

2

問題を追跡しました。リンカオプションに/LARGEADDRESSAWAREフラグを追加するのを忘れてしまった。

また、スティーブンチュ氏の答えは、scanLine()ヒントで本当に感謝しています。まず、メモリを節約します。次に、それは本当にずっと高速です。

これで、私が望む目的であった32000x16000ピクセルまでの画像を安全に作成できます。

関連する問題