2011-01-04 28 views
10

Çeşitli bitmapler ve simgeler için png formatlı veya ham ikili verileri gösterebilen bir veritabanından bazı blob verilerini yükleyen bir uygulamam var. Bu bir std::vector<unsigned char>Bellek arabelleğinden HBITMAP oluşturma

'de depolanmaktadırağaç görünümlerinde, araç çubuğu resimlerinde vb. Çeşitli görüntüleri görüntülemek için kullanıyorum ama bellek içindeki verilerden bitmapler oluşturuyorken sorun, piksellerin eksik olması gibi bulanık görünüyor. aşağıdaki gibi yapıyor bir şey:

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

şimdi sadece geçici bir dosyaya vektöründe() verileri yazıyorum ve ardından yeniden okumak için LoadImage kullanarak ve bundan HBITMAP oluşturmak için bu sorunu çözmek için . Bu mükemmel çalışır, ancak bu kuşkusuz utanmaz bir kesmek ve tamamen ümitsiz olmalı.

Çevrimi araştırdım, ancak bellekten "doğru şekilde" nasıl "doğru" oluşturulduğuna dair gerçekten iyi örnekler bulamadım. Resim listesine eklenecek bu bitmap'leri herhangi bir dosya i/o olmadan ve mümkünse verileri kopyalayarak sınırlı miktarlarda oluşturmak istiyorum.

Bunu yapmanın en iyi yolunu bulmak ve açıkça pencerelere özgü kodlar gayet iyi.

GÜNCELLEME:

Sonunda CreateCompatibleBitmap, CreateDIBitmap ve CreateDIBSection ile oynamaya başladı JDV cevabı dayanarak

. Bunların tümü, önceki bulanık bitmap'ler yerine güzel siyah bitmap'ler oluşturmayı başardı, bu yüzden tekrar yanlış bir şeyler yapmalıyım ve tahminim, bu bitmap oluşturma işleminin, GetDC(NULL) kullanarak ekranın dc veya penceresinin hiçbir konseptinin bulunmadığı bir nesnede yapıldığından ve CreateCompatibleDC(NULL) iyi değil. Örnek kod: Şimdi tabii tamamen HBITMAP kaçınarak ve CBitmap sınıfla doğrudan çalışarak belki bu konuda gitmek için daha basit bir yolu olmalı var düşünüyorum

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

? Görüntüyü CImageList'a eklemeye başladığımda zaten CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask) kullanıyorum. CBitmap nesnesini std::vector<unsigned char>'dan başlatmanın basit bir yolu bilen var mı?

+0

başına değiştirildi. Yeni bir soru göndermek ve eskisine bağlantı kurmaktan çekinmeyin. –

+0

Üzgünüm bir adım geri döndü ve GDI arazisine gittiğimin tek sebebinin CImageList'e eklerken FromHandle yöntemini kullanmamın sebebi olduğunun farkına vardım ... MFC CBitmap GDI çağrılarını yine de çok benzer şekilde sarar. – AJG85

cevap

3

GdiPlus'ı kullanma Oldukça iyi çalışan ve diş çekmeyi gerektirmeyen bir şey buldum!

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

Düzenleme

: o cevapları geçersiz kılar gibi yeni bir anlam soruyu düzenlemek etmeyiniz Jegatheesh

+1

Ve HBITMAP'ı Gdiplus :: Bitmap * 'den nasıl edinebilirsiniz? –

5

CreateCompatibleBitmap kullanın ve verilerinizle doldurmak için SetDIBits numaralı telefonu arayın. Bunlar benim çalıştığım işlevleri ve SetDIBits oldukça esnek olmasına rağmen, ayrıntılı.

MFC yıllarımda, performans sorunları nedeniyle CreateBitmap'dan kaçınıldı.

+1

CreateDIBitmap'a bakıyorum, temel olarak DC uyumlu bir bitmap oluşturduğunu söyleyebileceğim şeyden sonra CBM_INIT bayrağını belirtirseniz SetDIBits eşdeğerini çağırıyor. Pencere API'sinde parametreler ve yapı üyeleri olan herkesin vurulması gerekir. – AJG85

+0

Oh, doğru, CreateDIBitmap da vardı. –