Tengo una aplicación con la que carga algunos datos blob de una base de datos que puede representar png con formato o sin formato binario de datos para varios mapas de bits y los iconos. Este se almacena en un std::vector<unsigned char>

Estoy usando CImageList objetos para mostrar varias imágenes en vistas de árbol, la barra de herramientas de imágenes, etc, pero el problema es la creación de mapas de bits a partir de los datos en la memoria están saliendo a la luz difusa, como si los píxeles que faltan cuando se hace algo como la siguiente:

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

Para evitar este problema, por ahora estoy simplemente la escritura de los datos() en el vector a un archivo temporal y, a continuación, utilizando LoadImage a la lectura y la creación de la HBITMAP de que. Esto funciona perfectamente, sin embargo, que es sin duda una descarada hack y debe ser completamente innecesario espero.

He mirado por internet pero no he encontrado ninguna realmente buenos ejemplos de cómo «correctamente» crear hbitmaps de la memoria. Me gustaría ser capaz de crear estos mapas de bits para ser añadido a la lista de imágenes sin ningún tipo de archivo de e/s y cantidades limitadas de la copia de los datos en torno a si es posible.

Buscando la mejor manera de hacer esto y obviamente específicos de windows de código está bien.

ACTUALIZACIÓN:

Basado en jdv la respuesta comencé a jugar con CreateCompatibleBitmap CreateDIBitmap, y finalmente CreateDIBSection. Todos estos acabó creando encantadora negro mapas de bits en lugar de la anterior aproximada de mapas de bits así que debo estar haciendo algo mal otra vez y mi conjetura es desde este mapa de bits de la creación que se hace en un objeto que no tiene ningún concepto de la dc de pantalla o de la ventana que el uso de GetDC(NULL) y CreateCompatibleDC(NULL) no son buenas. Ejemplo de código:

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

Estoy ahora, por supuesto, el pensamiento tiene que haber una manera más fácil de ir sobre esto tal vez por evitar el HBITMAP por completo y trabajando directamente con CBitmap clase? Cuando llega la hora de agregar la imagen a la CImageList estoy usando CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask) de todos modos. ¿Alguien sabe una manera sencilla para inicializar un CBitmap objeto de un std::vector<unsigned char>?

Por favor, no editar la pregunta a un nuevo significado a medida que invalida las respuestas. Siéntase libre de publicar una nueva pregunta y el enlace a la antigua.
Lo siento, solo dio un paso atrás y se dio cuenta de que la única razón por la que estaba pasando en GDI tierra era porque yo estaba usando el FromHandle método cuando se añade a la CImageList … MFC CBitmap simplemente ajusta el GDI llamadas de todos modos, así que es muy similar.

OriginalEl autor AJG85 | 2011-01-04

2 Comentarios

  1. 5

    Yo uso la CreateCompatibleBitmap y, a continuación, llamar a SetDIBits llenarla con tus datos. Estas son funciones que he visto para el trabajo, y SetDIBits es bastante flexible, aunque detallado.

    En mi MFC años, CreateBitmap fue evitado debido a la sospecha de problemas de rendimiento.

    Estoy buscando en la CreateDIBitmap ahora que puedo decir que básicamente crea un DC compatible mapa de bits y, a continuación, llama a un equivalente de SetDIBits si se especifica el CBM_INIT bandera. Quien parámetros con nombre y miembros de estructuras en la API de windows necesita para ser fusilados.
    Oh, a la derecha, también hubo CreateDIBitmap.

    OriginalEl autor

  2. 3

    Utilizando GdiPlus tengo algo que funciona bastante bien y no implica la extracción de los dientes!

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

    Edición: Cambiado por Jegatheesh

    Y cómo obtener HBITMAP de Gdiplus::Bitmap* ?

    OriginalEl autor AJG85

Dejar respuesta

Please enter your comment!
Please enter your name here