Question

J'ai une application qui charge certaines données blob sur une base de données qui peut représenter des données binaires au format .png ou brutes pour diverses bitmaps et icônes. Ceci est stocké dans un std::vector<unsigned char>

J'utilise CImageList objets pour afficher différentes images dans les vues d'arbres, des images de la barre d'outils, etc, mais le problème est la création de bitmaps à partir des données en mémoire sont coming out floue comme si elle les pixels manquants lorsque vous faites quelque chose comme ci-dessous:

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

Pour contourner ce problème pour l'instant je suis en train d'écrire simplement les données () dans le vecteur d'un fichier temporaire, puis en utilisant LoadImage de le lire en arrière et la création de la HBITMAP de cela. Cela fonctionne parfaitement mais qui est certes un hack sans vergogne et devrait être complètement inutile, je l'espère.

Je l'ai regardé autour en ligne, mais n'a pas trouvé de très bons exemples de la façon de « correctement » créer hbitmaps de la mémoire. Je voudrais être en mesure de créer ces bitmaps à ajouter à la liste d'images sans aucun fichier i / o et des quantités limitées de copie des données dans la mesure du possible.

Vous cherchez la meilleure façon de le faire et évidemment fenêtres code spécifique est très bien.

Mise à jour:

Sur la base de la réponse de jdv j'ai commencé à jouer avec CreateCompatibleBitmap, CreateDIBitmap, et enfin CreateDIBSection. Tous ces éléments ont fini par créer de belles bitmaps noires au lieu des bitmaps floues précédentes donc je dois faire quelque chose de mal à nouveau et je suppose depuis cette création bitmap est fait dans un objet qui n'a pas de concept de courant continu d'écran ou fenêtre en utilisant GetDC(NULL) et CreateCompatibleDC(NULL) ne sont pas bons. Exemple de code:

    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);

Je suis maintenant de penser bien sûr, il doit y avoir un moyen plus simple d'aller sur ce peut-être en évitant HBITMAP tout à fait et de travailler directement avec classe CBitmap? Quand il revient à ajouter l'image à la CImageList J'utilise CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask) de toute façon. Est-ce que quelqu'un connait un moyen simple d'initialiser un objet CBitmap d'un std::vector<unsigned char>?

Était-ce utile?

La solution 2

En utilisant GdiPlus je suis quelque chose qui fonctionne assez bien et ne comporte pas de tirer des dents!

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();
}

Modifier Changement par Jegatheesh

Autres conseils

J'utiliser CreateCompatibleBitmap, puis appelez SetDIBits pour le remplir avec vos données. Ce sont des fonctions que j'ai vu au travail, et SetDIBits est assez souple, bien bavard.

Dans mes années MFC, CreateBitmap a été évité en raison de problèmes présumés de performance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top