12
votes

Créer HBITMAP à partir de tampon de mémoire

J'ai une application qui charge des données blobées d'une base de données pouvant représenter des données binaires formatées ou brutes PNG pour divers bitmaps et icônes. Ceci est en cours de stockage dans un std :: vecteur code>

J'utilise CIMAGELIST code> Objets pour afficher diverses images dans les vues des arbres, les images de la barre d'outils, etc. mais Le problème consiste à créer des bitmaps à partir des données de la mémoire, sortez floue comme s'il manque des pixels manquants lorsque vous faites quelque chose comme ci-dessous: P>

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


2 commentaires

S'il vous plaît ne modifiez pas une question à une nouvelle signification car elle invalide les réponses. N'hésitez pas à poster une nouvelle question et de lien vers l'ancien.


Désolé, il suffit de prendre un pas en arrière et de réaliser la seule raison pour laquelle j'allais dans GDI Terre était parce que j'utilisais la méthode de Thandle lors de l'addition de Cimagelist ... MFC Cbitmap enveloppe simplement les appels GDI de toute façon, il est donc très similaire.


3 Réponses :


6
votes

J'utiliserais CreateCompatibleBitmap , puis appelez setdibits pour le remplir avec vos données. Ce sont des fonctions que j'ai vues à travailler et que les SetdiBits sont assez flexibles, bien que verbeux.

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


1 commentaires

Je regarde CreateibitMap maintenant, à partir de ce que je peux dire crée essentiellement un bitmap compatible CC, puis appelle un équivalent de SetDibits si vous spécifiez le drapeau CBM_INIT. Quiconque nommé Paramètres et membres des Structs dans Windows API doivent être abattus.



3
votes

Utiliser gdiplus j'ai quelque chose qui fonctionne assez bien et n'implique pas de tirer des dents! xxx

EDIT: Changé par Jegatheesh


2 commentaires

Et comment obtenir HBITMAP de GDIPLUS :: bitmap * ?


@nick_n_a: gdipreatehbitmapfrombitMap ?



0
votes

Une légère variation sur le Réponse fournie par AJG85 , qui emploie ShCreatememStream à la place de CreattreamonHglobal code>. shCreatememStream code> a été introduit en tant qu'API publique sous Windows Vista et offre au profit de la création d'un iStream code> sur une région existante en mémoire, évitant ainsi une allocation de mémoire supplémentaire:

#include <Shlwapi.h>
#include <atlimage.h>
#include <comdef.h>
#include <comip.h>

#include <vector>

#pragma comment(lib, "Shlwapi.lib")
#if defined(_DEBUG)
#    pragma comment(lib, "comsuppwd.lib")
#else
#    pragma comment(lib, "comsuppw.lib")
#endif


HBITMAP from_data(std::vector<unsigned char> const& data)
{
    if (data.empty())
    {
        _com_issue_error(E_INVALIDARG);
    }

    auto const stream { ::SHCreateMemStream(&data[0], static_cast<UINT>(data.size())) };
    if (!stream)
    {
        _com_issue_error(E_OUTOFMEMORY);
    }
    _COM_SMARTPTR_TYPEDEF(IStream, __uuidof(IStream));
    IStreamPtr sp_stream { stream, false };

    CImage img {};
    _com_util::CheckError(img.Load(sp_stream));

    return img.Detach();
}


0 commentaires