Вопрос

У меня есть приложение, которое загружает некоторые данные Blob из базы данных, которая может представлять форматированные PNG или необработанные двоичные данные для различных растровых карт и значков. Это хранится в std::vector<unsigned char>

я использую CImageList Объекты для отображения различных изображений в представлениях деревьев, изображениях панели инструментов и т. Д., Но проблема заключается в создании растровых изображений из данных в памяти, выпускаются нечеткими, как будто не хватает пикселей, когда они делают что -то вроде ниже:

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

Чтобы обойти эту проблему на данный момент, я просто записываю данные () в векторе во временный файл, а затем использую LoadMage, чтобы прочитать его обратно и создать HBITMAP из этого. Это работает отлично, однако, по общему признанию, бесстыдный взлом и должен быть совершенно ненужным, я бы надеялся.

Я осмотрел онлайн, но не нашел действительно хороших примеров того, как «правильно» создавать HBITMAP из памяти. Я хотел бы иметь возможность создавать эти растровые карты, которые будут добавлены в список изображений без какого -либо ввода -вывода файла и ограниченных количеств копирования данных, если это возможно.

Ищу лучший способ сделать это, и, очевидно, специфический код Windows в порядке.

ОБНОВИТЬ:

Основываясь на ответе JDV, я начал играть с CreateCompatibleBitmap, CenectibitMap и, наконец, Cenelebsection. Все это закончилось тем, что создали прекрасные черные растровые карты вместо предыдущих нечетких растровых карт, поэтому я должен делать что -то не так, и я предполагаю, что это создание растрового изображения делается в объекте, который не имеет концепции экрана DC или окна, которое использует GetDC(NULL) а также CreateCompatibleDC(NULL) плохо. Образец кода:

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

Теперь я, конечно, думаю, что должен быть более простой способ сделать это, возможно, вообще избегая HBITMAP и работая напрямую с CBitmap учебный класс? Когда дело доходит до добавления изображения в CImageList я использую CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask) тем не мение. Кто -нибудь знает простой способ инициализации CBitmap объект из а std::vector<unsigned char>?

Это было полезно?

Решение 2

Используя Gdiplus, у меня есть что -то, что работает довольно хорошо и не включает в себя вытягивание зубов!

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

Редактировать: Изменен на Jegateesh

Другие советы

Я бы использовал CreateCompatibleBitmap, а затем позвоните SetDIBits Чтобы заполнить его своими данными. Это функции, которые я видел, и SetDibits довольно гибкие, хотя и многословные.

В мои годы MFC, CreateBitmap был избегал из -за подозреваемых проблем с производительностью.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top