2011-01-04 27 views
10

Tôi có một ứng dụng tải một số dữ liệu blob ra khỏi cơ sở dữ liệu có thể đại diện cho dữ liệu nhị phân được định dạng hoặc dữ liệu nhị phân cho các bitmap và biểu tượng khác nhau. Này đã được lưu trữ trong một std::vector<unsigned char>Tạo HBITMAP từ bộ đệm

Tôi đang sử dụng CImageList đối tượng để hiển thị hình ảnh khác nhau trong quan điểm cây, hình ảnh thanh công cụ, vv nhưng vấn đề là tạo ra bitmap từ các dữ liệu trong bộ nhớ được sắp ra mờ như thể nó còn thiếu pixel khi làm một cái gì đó như dưới đây:

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

để làm việc xung quanh vấn đề này cho bây giờ tôi chỉ đơn giản là viết ra các dữ liệu() trong vector vào một tập tin tạm thời và sau đó sử dụng LoadImage để đọc nó trở lại và tạo ra HBITMAP từ đó . Điều này hoạt động hoàn hảo tuy nhiên đó là thừa nhận là một hack không biết xấu hổ và nên hoàn toàn không cần thiết tôi sẽ hy vọng.

Tôi đã xem xét trực tuyến nhưng chưa tìm thấy bất kỳ ví dụ thực sự hay về cách "đúng" tạo các ảnh hưởng từ bộ nhớ. Tôi muốn có thể tạo các bitmap này để thêm vào danh sách hình ảnh mà không cần bất kỳ tập tin nào và số lượng giới hạn sao chép dữ liệu xung quanh nếu có thể.

Tìm cách tốt nhất để làm điều này và rõ ràng là cửa sổ mã cụ thể là tốt.

UPDATE:

Dựa trên câu trả lời jdv của tôi bắt đầu chơi với CreateCompatibleBitmap, CreateDIBitmap, và cuối cùng CreateDIBSection. Tất cả những điều này đã tạo ra bitmap màu đen đáng yêu thay vì các bitmap mờ trước đó, vì vậy tôi phải làm điều gì đó sai một lần nữa và tôi đoán là vì việc tạo bitmap này đang được thực hiện trong một đối tượng không có khái niệm về màn hình dc hoặc cửa sổ sử dụng GetDC(NULL)CreateCompatibleDC(NULL) không tốt. Mẫu mã:

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

bây giờ tôi tất nhiên suy nghĩ đó đã có được một cách đơn giản hơn để đi về vấn đề này có lẽ bằng cách tránh các HBITMAP hoàn toàn và làm việc trực tiếp với CBitmap lớp học? Khi nói đến việc thêm hình ảnh vào CImageList, tôi vẫn sử dụng CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask). Có ai biết một cách đơn giản để khởi tạo một đối tượng CBitmap từ một std::vector<unsigned char>?

+0

Xin đừng sửa một câu hỏi để một ý nghĩa mới vì nó làm mất hiệu lực các câu trả lời. Vui lòng đăng câu hỏi và liên kết mới lên câu hỏi cũ. –

+0

Xin lỗi chỉ cần lùi lại một bước và nhận ra lý do duy nhất tôi đi vào đất GDI là bởi vì tôi đã sử dụng phương pháp FromHandle khi thêm vào CImageList ... MFC CBitmap đơn giản là kết thúc tốt đẹp các cuộc gọi GDI, vì vậy nó rất giống nhau. – AJG85

Trả lời

3

Sử dụng GdiPlus Tôi có một thứ hoạt động khá tốt và không liên quan đến việc kéo bất kỳ răng nào!

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

Edit: thay đổi mỗi Jegatheesh

+1

Và cách lấy HBITMAP từ 'Gdiplus :: Bitmap *'? –

5

Tôi muốn sử dụng CreateCompatibleBitmap và sau đó gọi SetDIBits để điền dữ liệu đó vào dữ liệu của bạn. Đây là những chức năng tôi đã thấy để làm việc, và SetDIBits là khá linh hoạt, mặc dù tiết.

Trong năm MFC của tôi, CreateBitmap đã bị tránh do các vấn đề về hiệu suất bị nghi ngờ.

+1

Tôi đang nhìn vào CreateDIBitmap bây giờ mà từ những gì tôi có thể nói về cơ bản tạo ra một bitmap tương thích DC và sau đó gọi một tương đương với SetDIBits nếu bạn chỉ định cờ CBM_INIT. Bất cứ ai đặt tên tham số và thành viên của cấu trúc trong cửa sổ API cần phải được bắn. – AJG85

+0

Ồ, đúng vậy, cũng có CreateDIBitmap. –

Các vấn đề liên quan