leeres Bitmap erstellen



  • Hallo,

    Warum funktioniert das in dieser Form nicht:

    dummyBmp->CreateBitmap( iImgWidth, iImgHeight, 1, iBitDepth, NULL );
    CDC MemDC;
    CDC* pDC = GetDC();
    MemDC.CreateCompatibleDC( pDC );
    MemDC.SelectObject( dummyBmp );
    m_bmpBitmap->CreateCompatibleBitmap( &MemDC, iImgWidth, iImgHeight );
    

    jetzt mal davon abgesehen, daß die zwei CBitmap* 's (m_bmpBitmap und dummyBmp) hier nicht initialisiert sind (sind sie im Normalfall natürlich 🙂 ). Derzeit löse ich das in allen Anwenugen so, das ich Resource Bitmaps von 2x2 Pixeln Größe benutze (in verschiedenen Farbtiefen). Die lade ich dann je nach neu zu erstellendem Bitmap und passe dann die Größe des Bitmaps mit SetBitmapDimension (..) an.
    Klar das funktioniert, ist aber nicht besonders schön gelöst. Alle anderen Wege führen immer über Files auf Platte (Konvertierungsroutinen mit entsprechender Manipulation der Bildbytes, sowie des BITMAPINFOHEADERs). Hat da irgendwer eine Idee?

    Danke



  • Was verstehst du unter einem leeren Bitmap?



  • Einfach ein neues CBitmap - Object einer bestimmten Größe, Breite und Farbtiefe. Halt nicht aus einem File geladen sondern komplett "neu - selbsterstellt" :). Selbst bei Codeproject.com hab ich nichts dergleichen gefunden. Das Problem an der Sache ist, daß man ja auch Bmps erstellen möchte in anderen Formaten als dem aktiven Devicekontext erstellen möchte (z.B. Grauwert Bilder).

    Ich hab jetzt eine halbwegs passable Lösung über den Umweg eines DIB gebastelt (vorerst nur für 24 Bit - BMPs):

    CBitmap* CreateBmp(void)
    {
        CClientDC aDc(NULL);
        BITMAPINFO aBmpsInfo;
        aBmpsInfo.bmiHeader.biSize = sizeof(aBmpsInfo);
        aBmpsInfo.bmiHeader.biHeight = 576;
        aBmpsInfo.bmiHeader.biWidth = 768;
        aBmpsInfo.bmiHeader.biPlanes = 1;
        aBmpsInfo.bmiHeader.biBitCount = 8;
        aBmpsInfo.bmiHeader.biCompression = BI_RGB;
        aBmpsInfo.bmiHeader.biSizeImage = (aBmpsInfo.bmiHeader.biBitCount/8) * aBmpsInfo.bmiHeader.biHeight * aBmpsInfo.bmiHeader.biWidth;
        aBmpsInfo.bmiHeader.biClrUsed = 0;//use max colors
        aBmpsInfo.bmiHeader.biClrImportant = 0;//use max colors
    
        BYTE* pbBytes = new BYTE[aBmpsInfo.bmiHeader.biSizeImage];
        HBITMAP hDib = CreateDIBSection( aDc.m_hDC, &aBmpsInfo, DIB_RGB_COLORS, (void**)&pbBytes, NULL, NULL ); //DIB_PAL_COLORS
    
        CBitmap* newBmp = new CBitmap;
    
        newBmp->Attach( hDib );
        return newBmp;
    }
    

    Ich habe keine Ahnung warum meine vorherige Variante nicht funktioniert. Naja, viel Wege füren nach Rom....



  • Nochmal: Was für Eigenschaften hat ein leeres BMP? Hat es zu Beginn eine bestimmte Farbe? Oder was?
    Kapier dein Problem net 🙂



  • Also: Ein leeres Bitmap zeichnet sich durch eine Dimension X, Dimension Y und eine bestimmte Farbtiefe (8, 24 Bit) aus. weiterhin sind in diesen Farbtiefen Grauwert und Farbdarstellungen möglich (d.h., die Art und Weise, wie die Pixelinformation dann auf dem Bildschirm repräsentiert wird). Der Wert den jeder Pixel eines "leeren" Bitmaps (neues Bitmap trifft es glaube ich besser)nach Erstellung annimmt ist natürlich der, den man initialisiert hat.
    So nehme z.B. Bilddaten in einem bestimmten Format auf. D.h., ich bekomme vom Framegrabber ein BYTE Array mit Pixeldaten und muß mir nun daraus ein entsprechendes Bitmap Basteln. Anderes Beispiel ist die Darstellung eines Farbkanals eines RGB Bildes in eine 8Bit Grauwert-Bild.
    In jedem Fall muß ein neues Bitmap erstellt werden, welches unabhängig vom DC die jeweiligen Bilddaten repräsentieren kann.

    Oder lachst du mich gerade aus, weil es eine gaaaanz einfache Lösung dafür gibt? 🙂



  • Da hast Du Dich aber völlig unklar ausgedrückt am Anfang!
    Aber Du betrachtest das ganze von der falschen Seite. Besser ist folgende Betrachtungsweise:
    Du hast 1 BITMAPINFOHEADER-Struktur sowie einen Zeiger auf ein ByteArray mit DIB-Daten (device-unabhängige Bitmapdaten).
    Je nachdem, wie Du jetzt die BITMAPINFOHEADER-Struktur initialisierst, werden die DIB-Daten anders ausgelesen. Zum Anzeigen verwendet man die Funktion SetDIBitsToDevice oder StretchDIBits!
    Man kann aber auch die DrawDib-Funktionen nehmen, die aus dem Multimedia (Video)-Bereich kommen. Dazu steht in der MSDN:

    Collectively, the DrawDib functions are similar to the StretchDIBits function in that they provide image-stretching and dithering capabilities. However, the DrawDib functions support image decompression, data-streaming, and a greater number of display adapters.



  • Heißt das sozusagen es wäre günstiger in diesem Fall gleich nur mit DIBs zu arbeiten? Sorry, Ich habe bisher auch nur mit DDBs geabeitet.
    Das wäre auch schon gleich die nächste Frage: 16Bit Grauwertdarstellung wäre ja demzufolge nur mit DIBs möglich oder? Oder kann ein GDI-Object(HBITMAP) mit 16Bit Grauwert überhaupt umgehen?

    Danke



  • 1. Wenn man auf den DIB-Speicher zugreifen muss, um zu verarbeiten und gleichzeitig darzustellen, ist es besser, DIBs zu nehmen.

    2. 16Bit Graustufendarstellung ist grundsätzlich nicht möglich, da musst Du wohl manuell ein Downsampling vornehmen!


Anmelden zum Antworten