Pregunta

Tengo una aplicación que algunas cargas de datos blob fuera de una base de datos que puede representar datos binarios con formato png o prima para diversos mapas de bits e iconos. Esto está siendo almacenado en una std::vector<unsigned char>

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

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

Para evitar este problema, por ahora simplemente estoy escribiendo los datos () en el vector en un archivo temporal y luego usando LoadImage para leer de nuevo y crear la HBITMAP de eso. Esto funciona perfectamente sin embargo, que es sin duda un truco descarado y debe ser completamente innecesario espero.

He mirado alrededor en línea, pero no han encontrado ningún realmente buenos ejemplos de cómo "adecuadamente" crear hbitmaps de la memoria. Me gustaría ser capaz de crear estos mapas de bits que se añade a la lista de imágenes sin ningún tipo de archivo de E / S y cantidades limitadas de copiar los datos en torno a si es posible.

Búsqueda de la mejor manera de hacer esto y obviamente ventanas código específico está muy bien.

ACTUALIZACIÓN:

Sobre la base de la respuesta de jdv que empezó a jugar con CreateCompatibleBitmap, CreateDIBitmap, y finalmente CreateDIBSection. Todos ellos terminaron creando preciosos mapas de bits negros en lugar de los mapas de bits difusos anteriores, así que deben estar haciendo algo mal otra vez y yo creo que es desde esta creación de mapa de bits que se está haciendo en un objeto que no tiene un concepto de la CC de la pantalla o ventana que el uso de GetDC(NULL) y CreateCompatibleDC(NULL) no son buenos. Código de ejemplo:

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

Ahora estoy de pensar supuesto que tiene que haber una manera más sencilla de hacer esto quizás evitando la HBITMAP por completo y trabajando directamente con la clase CBitmap? Cuando se llega a la adición de la imagen a la CImageList estoy usando CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask) de todos modos. ¿Alguien sabe una manera simple para inicializar un objeto CBitmap de un std::vector<unsigned char>?

¿Fue útil?

Solución 2

El uso de GdiPlus Tengo algo que funciona bastante bien y que no implique ningún tirando 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();
}

Editar: cambiado por Jegatheesh

Otros consejos

Yo usaría CreateCompatibleBitmap y, a continuación, llamar SetDIBits a llenarlo con sus datos. Estas son las funciones que he visto a trabajar, y SetDIBits es bastante flexible, aunque verbosa.

En mis años de MFC, CreateBitmap se evitó debido a problemas de rendimiento sospechosos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top