BitBlt kann nur schwarzweiss
-
Hallo, ich versuche verzweifelt an schnelle Windows API - Graphik zu kommen. Aus irgendeinem Grunde kann er keine
Farbe mit dem BitBlt Befehl machen. Es funktioniert nur mit einem nBitCount von 1 im Erzeuger
der Bitmap-Datenstruktur mit CreateBitmap. Jeder anderer Parameter hat zur Folge, daß gar kein
Bild kommt. Der direkte SetPixel - Befehl kann Farbe, nur der ist zu langsam. Ich habs unter MinGW/bin
compiliert, aber auch mit Dev C++ probiert, es ist immer der gleiche Mist. Ich habe Windows 10. Weiss Jemand, woran es liegen könnte ?HWND wnd = GetConsoleWindow(); HDC hdc = GetDC( wnd ); char ImagAry[300000]; for(int i=0; i<300000; i++) { ImagAry[i] = 5; }; HBITMAP Imag = CreateBitmap( 300, // [in] int nWidth, 300, // [in] int nHeight, 1, // [in] UINT nPlanes, 1, // [in] UINT nBitCount, ImagAry // [in] const VOID *lpBits ); HDC memDC = CreateCompatibleDC( hdc ); // HBITMAP hbmp = ske_CreateDIB32(mWidth, mHeight); HBITMAP holdbmp = (HBITMAP) SelectObject(memDC, Imag); // hbmp); GetObject( (HGDIOBJ) Imag, sizeof( Imag ) , &Imag); for(int j=0; j<255; j+=26) for(int i=0; i<255; i++) SetPixel( memDC, i, j, RGB(200,i, 0) ); if ( BitBlt( hdc, 4,4, 300, 300, memDC, 1, 1, SRCCOPY) ) Kz('S'); // Selbstgemachter Konsolenoutput. else Kz('F'); DeleteDC( memDC ); DeleteObject( Imag ); ReleaseDC( wnd , hdc);
-
Überprüfe mal den Rückgabewert (sowie Fehlerwert mittels
GetLastError
) von BitBlt.
-
@Th69 Der boolesche Rückgabewert von BitBlt war immer true, obwohl er gar nichts
angezeigt hat.
-
Der GetLastError-Wert nach dem Aufruf von BitBlt war immer 0, egal ob er
was angezeigt hat, oder nicht.
-
@rsobe sagte in BitBlt kann nur schwarzweiss:
for(int i=0; i<300000; i++) { ImagAry[i] = 5; };
Probiere doch mal bitte nBitCount auf 24 zu setzen und in ImagAry Zufallswerte zwischen 0 und 255 zu setzen.
-
@rsobe Du hast mein Beispiel von neulich noch?
Wie @Quiche-Lorraine vorgeschlagen hat, sollte
nBitCount
schon 24 oder 32 sein. Letzteres macht die Adressierung etwas simpler und hat auch einen Alpha-Kanal für Transparenz (4. Byte jedes Pixels auf0xff
setzen für volle Deckraft/Sichtbarkeit).Bei 24 Bits auch die Dokumentation von CreateBitmap beachten:
Each scan line in the rectangle must be word aligned (scan lines that are not word aligned must be padded with zeros)
Ich bin mir nicht ganz sicher ob hier ein Windows-
WORD
(2 Bytes) oder ein CPU-Word (4 oder 8 Bytes) gemeint ist. Ich denke es ist ein Windows-WORD
. In jedem Fall werden mit 24 Bit mindestens bei einer ungeradenwidth
zusätzliche Padding-Bytes benötigt. Bei 32 Bits braucht man das nicht, die haben immer ein 4-Byte-Alignment.Und um einer eventuellen Folgefrage vorzubeugen: Windows-Bitmaps stehen im Speicher auf dem Kopf. In meinem Beispiel konnte ich in
BITMAPINFO
einfach eine negative Höhe angeben, damit das richtig herum angezeigt wird. Ich weiss nicht, ob das mitCreateBitmap
auch funktioniert, aber das kannst du ja mal versuchen, wenn deine Pixel kopfüber angezeigt werden.
-
@Quiche-Lorraine sagte in BitBlt kann nur schwarzweiss:
@rsobe sagte in BitBlt kann nur schwarzweiss:
for(int i=0; i<300000; i++) { ImagAry[i] = 5; };
Probiere doch mal bitte nBitCount auf 24 zu setzen und in ImagAry Zufallswerte zwischen 0 und 255 zu setzen.
Hab ich gemacht, bringt nichts, es kommt nur schwarz weiss mit nBitCount == 1 oder
gar keine Bildausgabe, bei jeder anderen Parameter-Einstellung. Das Farbdaten-Alignment habe ich natürlich erstmal ignoriert, für den Test. Dann
greift er sich halt irgendwelche Daten. Aber es sollte wengistens erstmal schnell bunt werden.
Macht er nicht, vielleicht hat die Bibliothek MinGW/lib/gdi32.a eine Macke ??Ich checke mal, was es mit BITMAPINFO auf sich hat.
-
@rsobe In meinem Beispiel damals habe ich auch das Bitmap mit
CreateDIBSection
erzeugt. Vor allem wegenThe CreateDIBSection function creates a DIB that applications can write to directly.
Die Pixeldaten, die man
CreateBitmap
übergibt, werden sehr wahrscheinlich nur für die einmalige Initialisierung verwendet. Nachträglich inImagAry
zu schreiben wird vermutlich das Bitmap nicht mehr verändern.ImagAry
wird also beiCreateBitmap
in das Bitmap kopiert, währendImagAry
bei derCreateDIBSection
-Variante zum Pixel-Speicher des Bitmaps gemacht wird.Das Pixelformat und die Dimensionen des Bitmap werden bei
CreateDIBSection
in der BITMAPINFO-Struktur definiert, die man der Funktion mit übergeben muss (als Pointer auf dasstruct
).
-
@Finnegan sagte in BitBlt kann nur schwarzweiss:
CreateDIBSection
Danke das ist der Denkanstoß. In der HBITMAP -Struktur, die anscheinend gekapselt ist, steckt offensichtlich noch
mehr drin, auch irgendwelche Farbinfos, das muss ich jetzt mal untersuchen.