SetPixel() grausam langsam - gehts schneller?
-
Hallo zusammen,
folgende Ausgangssituation:Ich habe ein Bild, in dem die Pixelinformation umkomprimiert vorliegen (KEIN Bitmap, sondern ein selbst gebautes Format).
Diese Bildinformationen will ich in einer MFC Anwendung in einem Dialogfenster auf den Schirm schmeißen.
Mein erster (naiver) Ansatz hierfür ist SetPixel über CClientDC und zwei for-Schleifen zu benutzen.
Das ist aber grausam langsam - man kann quasi den Pixeln beim gemalt werden zugucken.Meine Frage ist daher, geht es irgendwie schneller, reine Pixelinformationen, die in einer Matrix vorliegen, auf dem Schirm darzustellen.
Grüße und schon mal Danke für eventuelle Tips!
-
Das schnellste ist immer noch:
GetDIBits
-
wenn ich das richtig sehe, braucht man für GetDIBits doch auch ein Bitmap, das ich nicht habe...
int GetDIBits(
HDC hdc, // handle to DC
HBITMAP hbmp, // handle to bitmap
UINT uStartScan, // first scan line to set
UINT cScanLines, // number of scan lines to copy
LPVOID lpvBits, // array for bitmap bits
LPBITMAPINFO lpbi, // bitmap data buffer
UINT uUsage // RGB or palette index
);Mein Ausgangspunkt ist ja eben, daß ich die Pixelinformationen nur einer Matrix vorliegen habe und nicht als Bitmap.
Mein Format sieht so aus:
PIC MyPic[x][y];
Kann ich das vorher in ein Bitmap umwandeln?
Beim Bitmap liegen die Pixelinformationen ja auch unkomprimiert in einer Matrix vor...
-
Um eine Bitmap wirst du nicht drum rum kommen. Der CDC braucht nun mal ein Zeichenobjekt mit einer Reference auf das Pixelarray, außer du machst es mit SetPixel das geht langsam, aber du brauchst kein Zeichenobjekt dafür.
Schau mal unter: http://atlc.sourceforge.net/bmp.html
wegen des Bitmap-Daten-Formates.
Ist warscheindlich am schnellsten wenn du es in eine Bitmap wandelst und mit dem Blit auf den Desktop, etc. donnerst.
-
mostrich schrieb:
PIC MyPic[x][y];
Was soll den PIC sein? Und warum verwendest Du jetzt SetPixel?
Du solltest ein Bitmap mit der passenden grö0e und Farbtiefe anlegen und dann die Bits dort manipulieren. In den DC kannst Du das ganze mit BitBlt zeichnen...
-
Jochen Kalmbach schrieb:
Was soll den PIC sein? Und warum verwendest Du jetzt SetPixel?
Das ist wie schon erwähnt ein eigenes Format erstellt vom Lehrstuhl an der Uni!
SetPixel verwende ich, da ich im Moment nichts besseres weiß...Wie kann ich denn aus den Pixelinformationen ein Bitmap anlegen?
Wenn ich das schaffen würde, hätte ich ja gewonnen.
-
CreateBitmapIndirect ?
-
Hier mal ein Ansatz wie man das machen könnte.
CBitmap *CreateBitmap(PCI ???) { CBitmap *Bitmap = new CBitmap(); if(Bitmap) { Bitmap->CreateBitmap(nWidth,nHeight,1,32,NULL); //Breite und höhe stetzen BITMAP bm; Bitmap->GetObject(sizeof(BITMAP), (LPSTR)&bm); DWORD *pPixels = (DWORD*)new BYTE[ bm.bmWidthBytes*bm.bmHeight ];//allocate memory for image //byte buffer for(/*y*/) { for(/*x*/) { //Hier Pixel setzen } } dwValue = Bitmap->SetBitmapBits(bm.bmWidthBytes*bm.bmHeight,bmpBuffer); delete[] pPixels ; return Bitmap; } return NULL; }
Muß man natürlich noch anpassen! Das Bitmap kannste dann mit SelectObject in den DC selecten und blitten
Gruß Matthias
-
Wow - danke!
CreateBitmap und CreateBitmapIndirect hören sich schon sehr gut an!Geschenke shoppen kann aber ganz schön anstrengend sein - daher werde ich das Ganze erst morgen ausprobieren...
-
Oder CreateDIBSection. Wenn man Glück hat (hängt vom Treiber und Speicherstand ab), schreibt man da direkt in den Grafikspeicher.
-
Hallo,
Ich habe ein Bild, in dem die Pixelinformation umkomprimiert vorliegen (KEIN >Bitmap, sondern ein selbst gebautes Format).
Diese Bildinformationen will ich in einer MFC Anwendung in einem Dialogfenster >auf den Schirm schmeißen.
Mein erster (naiver) Ansatz hierfür ist SetPixel über CClientDC und zwei >for-Schleifen zu benutzen.<vbg> ja, das habe ich auch mal vor langer Zeit so probiert.
Wenn Du aber mal Terabyte großen Daten zu tun hast ist
das etwas langsam ;-).Die GDI-Funktionen kannst Du alle vergessen. Die Einzig vernünftige
Möglichkeit, solche Daten anzuzeigen ist als DIB (Device Independent
Bitmap). Wenn dein PIC-Format halwebgs vernünftig ist, kannst Du vielleicht
eine Klasse ableiten, die nur den PIC UND BITMAPV4HEADER Header hat und
die Daten entsprechend mappt.Du musst dich allerdings fragen lassen, warum du das Rad bzw. das Bild
neu erfinden willst? Gibt es wirklich GUTE GRÜNDE dafür? Jetzt wäre
ein guter Teitpunkt dein Design nochmal kritisch zu überdenken!Ansonsten bleibt dir nur, ein DIB zu erstellen, dein PIC dort geeignet reinzukopieren und das anzuzeigen! Bitte nur 1:1 (BitBlt). Habe mich mal
umn ein Pixel verrechnet und hatte einen Performanceeinbruch von
über faktor 100!