Bitmap mit Visual Studio 2005 u. WinCE6.0: Ersatz für SetDIBits u. GetDIBits
-
Hallo,
ich versuche einen Minimal-Ersatz für obige Methoden für die DIBSECTION zu finden,
da diese auf meinem WinCE-Panel nicht vorhanden sind. Ich benötige nur diese
beiden, um eine Farbtransformation durchzuführen.Meine Bitmaps haben ausschliesslich 32 Bit Farbtiefe.
Ich habe folgende Methode geschrieben:
void CEnBitmap::GetDIBits2( HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPBITMAPINFO lpBmi, UINT usage ) { DWORD dwBitmapImageSize = BytesPerLine(lpBmi->bmiHeader.biWidth, lpBmi->bmiHeader.biBitCount) * abs(lpBmi->bmiHeader.biHeight); BITMAP bm; GetBitmap(&bm); ZeroMemory(lpvBits,(size_t)dwBitmapImageSize); // Transformation from 24 Bit to 32 Bit (RGBQUAD) for(int i=0,k=0; ((i<dwBitmapImageSize) && (k<bm.bmWidthBytes)); i+=4, k+=3){ CopyMemory((char*)lpvBits+i, (char*)bm.bmBits+k, sizeof(char)*3); CopyMemory( (char*)lpvBits+i+3, (char*)"0", sizeof(char));// "rgbReserved" Part } }
Also eigentlich brauche ich dafür nur die "LPVOID lpvBits".
Nun scheint es, als sei die erste Zeile der Bitmap OK, aber weiter bekomme ich
für die RGB-Werte, sowie für den "rgbReserved" Teil nur noch "0".Die Original-Version mit "GetDIBits" bringt die Werte korrekt.
Kann jemand meine Fehler finden und vielleicht auch erklären?
Grüsse
Helmut
-
Hallo,
inzwischen bin ich weitergekommen und finde mein Bildmuster aber nun als
schräggestelltes Bild und auf dem Kopf stehend wieder.
Das verstehe ich leider auch nicht.voidCEnBitmap::GetDIBits2( HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPBITMAPINFO lpBmi, UINT usage ) { BITMAP bm; GetBitmap(&bm); DWORD dwBitmapImageSize = BytesPerLine(lpBmi->bmiHeader.biWidth, lpBmi->bmiHeader.biBitCount) * abs(lpBmi->bmiHeader.biHeight); RGBTRIPLE* pTri = (RGBTRIPLE*) malloc(sizeof(RGBTRIPLE)*dwBitmapImageSize/4); RGBQUAD* pQud = (RGBQUAD*) malloc(sizeof(RGBQUAD)*dwBitmapImageSize/4); CopyMemory((RGBTRIPLE*)pTri, (RGBTRIPLE*)(bm.bmBits), sizeof(RGBTRIPLE)*dwBitmapImageSize/4); // Transformation from 24 Bit (RGBTRIPLE) to 32 Bit (RGBQUAD) for(int i=0; i<(dwBitmapImageSize/4); i++){ (pQud+i)->rgbBlue = (pTri+i)->rgbtBlue; (pQud+i)->rgbGreen = (pTri+i)->rgbtGreen; (pQud+i)->rgbRed = (pTri+i)->rgbtRed; (pQud+i)->rgbReserved = 0; } CopyMemory((RGBQUAD*)lpvBits, (RGBQUAD*)pQud, sizeof(RGBQUAD)*dwBitmapImageSize/4); free(pTri); free(pQud); }
-
Die "GetDIBits(..)" habe ich nun doch noch hinbekommen, zumindest für meinen Zweck,
mit reinen 32 Bit Bitmaps.Es lag mit daran, dass in der "BITMAP" Struktur die Zeilenlänge immer durch 2
teilbar sein muss. Der Vollständigkeit hier noch das Resultat:int CEnBitmap::GetDIBits2( HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPBITMAPINFO lpBmi, UINT usage ) { BITMAP bm; GetBitmap(&bm); DWORD dwBitmapImageSize = lpBmi->bmiHeader.biSizeImage; RGBQUAD* pQud = (RGBQUAD*) malloc(sizeof(RGBQUAD)*dwBitmapImageSize/4); RGBQUAD* pQudStart = pQud; DWORD dwValueBytesLine = bm.bmWidthBytes; if(bm.bmWidthBytes % 3 == 1) dwValueBytesLine = bm.bmWidthBytes-1; RGBTRIPLE* pTriLine = (RGBTRIPLE*) malloc(sizeof(char)*dwValueBytesLine); // Transformation from 24 Bit (RGBTRIPLE) to 32 Bit (RGBQUAD) for(int i=0; i<bm.bmHeight; i++){ CopyMemory((char*)pTriLine, (char*)bm.bmBits+(i*bm.bmWidthBytes), sizeof(RGBTRIPLE)*dwValueBytesLine/3); for(int k=0; k<(dwValueBytesLine/3); k++){ (pQud+k)->rgbBlue = (pTriLine+k)->rgbtBlue; (pQud+k)->rgbGreen = (pTriLine+k)->rgbtGreen; (pQud+k)->rgbRed = (pTriLine+k)->rgbtRed; (pQud+k)->rgbReserved = 0; } if(i < bm.bmHeight-1) pQud += (bm.bmWidth); } CopyMemory((RGBQUAD*)lpvBits, (RGBQUAD*)pQudStart, sizeof(RGBQUAD)*dwBitmapImageSize/4); free(pTriLine); free(pQudStart); return cLines; }
Seltsamerweise wurde mit den Original-Methoden mit einer negativen Höhe gerechnet,
wodurch die Grafiken mit meiner Methode plötzlich auf dem Kopf standen.
Das habe ich noch geändert, und die Grafiken waren wieder normal.Aber vielleicht kann mir jemand mit der "SetDIBits(..)" noch weiterhelfen.
Hier habe ich momentan gar keinen Plan, was ich da machen muss!
Mit "SetBitmapBits(..)" hab ich es schon versucht. Bleibt alles schwarz.Sie ist in folgende Umgebung eingebettet ( "CEnBitmap" ist in CodeProject zu finden! )
// set the bits HDC hdc = GetDC(NULL); HBITMAP hbmSrc = ::CreateCompatibleBitmap(hdc, sizeDest.cx, sizeDest.cy); if (hbmSrc) { BITMAPINFO bi; BITMAP bm; bm = PrepareBitmapInfo32(bi, hbmSrc); if (bm.bmHeight > 0) { //if (SetDIBits(hdc, hbmSrc, 0, sizeDest.cy, pDestPixels, &bi, DIB_RGB_COLORS)) if (SetBitmapBits(bi.bmiHeader.biSizeImage, (void*)pDestPixels)) { // delete the bitmap and attach new DeleteObject(); bRes = Attach(hbmSrc); } } ::ReleaseDC(NULL, hdc); if (!bRes) ::DeleteObject(hbmSrc); }
Grüsse
Helmut