Domanda

Ho un'applicazione che carica alcuni dati BLOB da un database che può rappresentare png dati binari formattati o prime per vari bitmap e icone. Questo viene memorizzato in un std::vector<unsigned char>

sto usando CImageList oggetti da visualizzare diverse immagini in viste ad albero, le immagini della barra degli strumenti, ecc, ma il problema è la creazione di bitmap dei dati in memoria stanno uscendo sfocata come se manca pixel quando si fa qualcosa di simile di seguito:

std::vector<unsigned char> bits;
HBITMAP hbitmap = CreateBitmap(16, 16, 1, 32, bits.data());

Per risolvere questo problema, per ora sto semplicemente scrivendo i dati () nel vettore in un file temporaneo e quindi utilizzando LoadImage di leggerlo indietro e creare il HBITMAP da quello. Questo funziona perfettamente, tuttavia, che è certamente un hack spudorata e dovrebbe essere completamente inutile mi auguro.

Ho guardato intorno online, ma non ho trovato alcun veramente buoni esempi di come "correttamente" creare hbitmaps dalla memoria. Vorrei essere in grado di creare questi bitmap da aggiungere all'elenco delle immagini senza alcun file di I / O e una quantità limitata di copiare i dati in giro, se possibile.

cercando il modo migliore per farlo e, ovviamente, le finestre codice specifico va bene.

UPDATE:

In base a risposta di JDV ho iniziato a giocare con CreateCompatibleBitmap, CreateDIBitmap, e, infine, CreateDIBSection. Tutti questi finito per creare belle bitmap in bianco al posto delle precedenti bitmap sfocate quindi mi deve fare di nuovo qualcosa di sbagliato e la mia ipotesi è perché questo la creazione di bitmap è stato fatto in un oggetto che non ha il concetto della Dc o la finestra dello schermo che utilizza GetDC(NULL) e CreateCompatibleDC(NULL) non sono buone. codice di esempio:

    BITMAPINFO bmi;
    ZeroMemory(&bmi, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biHeight = 16;
    bmi.bmiHeader.biWidth = 16;
    bmi.bmiHeader.biPlanes = 1;

    HDC dc = CreateCompatibleDC(NULL);
    HBITMAP hbitmap = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, (void**)blobData.GetMember<FILEDATAFIELD_DATA>().data(), NULL, 0);

Ora sono ovviamente pensando ci deve essere un modo più semplice per andare su questo, forse evitando la HBITMAP tutto e lavorando direttamente con classe CBitmap? Quando si tratta di aggiungere l'immagine alla CImageList che sto utilizzando CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask) comunque. Qualcuno sa un modo semplice per inizializzare un oggetto CBitmap da un std::vector<unsigned char>?

È stato utile?

Soluzione 2

Utilizzando GDIplus Ho qualcosa che funziona abbastanza bene e non comporta alcun tirando denti!

Gdiplus::Bitmap* pBitmap = NULL;
IStream* pStream = NULL;

HRESULT hResult = ::CreateStreamOnHGlobal( NULL, TRUE, &pStream );
if(hResult == S_OK && pStream)
{
    hResult = pStream->Write(&bits[0], ULONG(bits.size()), NULL);
    if(hResult == S_OK)
        pBitmap = Gdiplus::Bitmap::FromStream(pStream);
    pStream->Release();
}

Modifica Cambiato per Jegatheesh

Altri suggerimenti

userei CreateCompatibleBitmap, e quindi chiamare SetDIBits a riempire con i tuoi dati. Si tratta di funzioni che ho visto al lavoro, e SetDIBits è abbastanza flessibile, anche se prolisso.

Nei miei anni MFC, CreateBitmap è stato evitato a causa di problemi di prestazioni sospette.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top