UnsignedChar-Array auf 32bit-device ausgeben(Farb-Palette anpassen)
-
Servus!
Ich sitze immer noch an meiner Kamera-Ansteuerung, die ich mittlerweile mit der MFC versuche anzugehen. Ich habe nun folgendes Problem: Meine HBITMAP-Struktur, die ich über
CClientDC dc(this ); CDC SpeicherDC; SpeicherDC.CreateCompatibleDC( &dc ); CBitmap Bild; //Bild.CreateBitmap(100,100,1,32,A); Bild.CreateCompatibleBitmap(&dc,100,100); //Bild.SetBitmapBits(100*100*4,A); BITMAP bm; Bild.GetBitmap(&bm);
bekomme, sagt mir, dass die Bitmap 32bit Farbtief hat. Das wundert mich nicht, da ich das Bitmap über CreateCompatibleBitmap bilde und der devicecontext halt 32bit Farbtiefe hat. Das Problem, das ich nun habe, ergibt sich, wenn ich das Array von unsignedchar-Werten, das ich von der Kamera bekomme, auf diesem devicecontext darstellen möchte. Bisher mache ich es so, dass ich zunächst ein 4mal so grosses Array einrichte(4*8bit=32bit) und jeden Pixelwert aus dem 8bit-Kamera-Array in 4facher Kopie in das "32bit-Array" übertrage. Bei einem stream(15 Bilder pro sek) ist das Durchlaufen der for-Schleife aber sehr unpraktisch, sodass ich nach einer Alternative gesucht habe. Ich habe fleissig gegooglet und bin auf die Farb-Paletten bzw. DIB-Bitmaps gestossen. Ich vermute, dass dies die Lösung für meine Probleme ist. Leider hat mein coden aber noch nicht zum erwünschten Erfolg geführt und so recht verstanden habe ich die ensprechenden Einträge in der msdn-Hilfe dazu auch nicht. Auch das duchforsten der hiesigen ForenBeiträge hat mich leider nicht wirklich weitergebracht. Der Beitrag, der am Vielversprechensten wirkte, war der folgende:[url] http://www.c-plusplus.net/forum/viewtopic-var-t-is-71624-and-highlight-is-palette.html[/url]. Innerhalb des Beitrags bin ich auf folgenden Abschnitt aufmerksam geworden:
DWORD sizeBI = sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD)); LPBITMAPINFO lpbi = (LPBITMAPINFO) new char[sizeBI]; ZeroMemory(lpbi,sizeBI); lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbi->bmiHeader.biWidth = width; lpbi->bmiHeader.biHeight = height; lpbi->bmiHeader.biPlanes = 1; lpbi->bmiHeader.biBitCount = 1; lpbi->bmiHeader.biCompression = BI_RGB; lpbi->bmiHeader.biSizeImage = ((((lpbi->bmiHeader.biWidth * lpbi->bmiHeader.biBitCount) + 31) & ~31) >> 3) * lpbi->bmiHeader.biHeight; /*for(int i = 0; i < 256; i++) { lpbi->bmiColors[i].rgbRed = i; lpbi->bmiColors[i].rgbGreen = i; lpbi->bmiColors[i].rgbBlue = i; }*/ lpbi->bmiColors[1].rgbRed = 255; lpbi->bmiColors[1].rgbGreen = 255; lpbi->bmiColors[1].rgbBlue = 255; aBmp = CreateDIBSection(hdc,lpbi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL);
Ich verstehe das so, dass eine DIB-Bitmap eingrichtet wird, deren Farb-Palette entsprechend angepasst wird. Ich vermute, dass ich den bisher auskommentierten Abschnitt der Palettenbesetzung verwenden muss, richtig? Leider funktioniert mein code aber nicht. Deshalb wende ich mich nun an Euch. Wie würdet Ihr an die Sache herangehen? Könnte man mir vllt ein paar Code-Schnipsel an die Hand geben?
Dank im Voraus!!!
-
Hatte ein ähnliches Problem und habe es mit CreateDIBSection gelöst; sollte auch bei dir funktionieren.
lpbi->bmiHeader.biBitCount = 1;
Du brauchst hier wohl
lpbi->bmiHeader.biBitCount = 8;
8 Bit per Pixel
for(int i = 0; i < 256; i++) { lpbi->bmiColors[i].rgbRed = i; lpbi->bmiColors[i].rgbGreen = i; lpbi->bmiColors[i].rgbBlue = i; }
Sollte stimmen: jeder Wert in deinem Array ist ein Index für bmiColors, dort ist die Farbe hinterlegt.
Für ein Graustufenbild schreibst du in bmiColors also die Werte so rein wie im Codeschnipsel.lpbi->bmiHeader.biSizeImage = ((((lpbi->bmiHeader.biWidth * lpbi->bmiHeader.biBitCount) + 31) & ~31) >> 3) * lpbi->bmiHeader.biHeight;
biSizeImage ist die Größe des Bilds in Bytes (z.B. width*height, wenn du 8 bit pro Pixel hast).
aBmp = CreateDIBSection(hdc,lpbi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL); CBitmap bitmap; bitmap.Attach(aBmp); // jetzt kannst du mit dem CBitmap "normal" arbeiten
-
@ihoernchen:
Übergibt "Attach" nicht Ownership an das CBitmap-Objekt?
Anders gesagt: bist du sicher dass man die Bitmap in diesem Beispiel noch von Hand (mit DeleteObject) löschen sollte?
-
hustbaer schrieb:
@ihoernchen:
Übergibt "Attach" nicht Ownership an das CBitmap-Objekt?
Anders gesagt: bist du sicher dass man die Bitmap in diesem Beispiel noch von Hand (mit DeleteObject) löschen sollte?Nein bin ich nicht
Aber die Doku interpretier ich mal so, dass CBitmap das Objekt löscht. Das ::DeleteObject ist wohl falsch.