2010-06-09 28 views
6

Làm cách nào để tải tài nguyên png vào trong CBitMap? Khi tôi thử nó không hoạt động.Tải tài nguyên png vào trong CBitMap

CImage image; 
image.LoadFromResource(AfxGetInstanceHandle(), IDB_PNG1); 
bitmap.Attach(image.Detach()); 

Nó cung cấp cho tôi loại tài nguyên lỗi không tìm thấy. Có cách nào khác để tải tài nguyên PNG không?

+0

Lỗi trong LoadFromResource hoặc trong phần đính kèm? – dwo

Trả lời

5

LoadFromResource sử dụng LoadImage nội bộ, nó không hỗ trợ PNG lần cuối tôi đã thử, mặc dù tài liệu nói gì. Bạn có thể liên kết với CxImage (xem trên codeproject) nhưng nó có rất nhiều công việc cho ít lợi ích thực sự.

Những gì tôi đã làm cuối cùng đã quên về PNG, sử dụng AlphaConv để chuyển đổi PNG thành bitmap Windows 32 bit và sử dụng CImage với những ảnh đó. Lợi thế bổ sung là bạn có thể sử dụng chúng với CBitmapButton, vv trong MFC mà không cần bất kỳ phép biến đổi nào.

Một cách khác để hack xung quanh nó là trích xuất nội dung tài nguyên sang tệp tạm thời, sau đó sử dụng CImage :: Tải để đọc nó từ đó. Nếu tôi bắt bạn làm điều đó ở một trong những căn cứ mã của tôi, tôi sẽ đấm vào mặt bạn;)

+2

+1 cho nhà phát triển thực sự bảo vệ cơ sở mã của mình – Lothar

1

Sử dụng thư viện như CxImage (http://www.xdp.it/cximage.htm) để làm tất cả việc nâng hạng nặng cho bạn. Mã này trở nên đơn giản như: -

CxImage image; 
if (image.LoadResource(<resource_instance_handle>, <resource_id>, CXIMAGETYPE_PNG)) 
{ 
    HBITMAP hbmp = image.CreateHBITMAP(); 
    ... do something with hbmp ... 
} 

(lưu ý rằng tôi đang viết mã này từ bộ nhớ - bạn có thể cần phải tinh chỉnh nó một chút để làm cho nó hoạt động!)

tôi sử dụng CxImage một rất nhiều cho đồ họa trong các chương trình của tôi và nó đơn giản hóa mọi thứ rất nhiều.

16

Nếu bạn đang sử dụng VS2008 hoặc mới hơn (Feature Pack MFC), bạn có thể sử dụng CPngImage mà xuất phát từ CBitmap và được chứa trong <afxtoolbarimages.h>

CPngImage image; 
image.Load(AfxGetInstanceHandle(), IDB_PNG1); 
bitmap.Attach(image.Detach()); 
+1

Tìm tốt! Tôi muốn nó được tài liệu tốt hơn, tôi thực sự có thể đã sử dụng điều này trong nhiều năm: ( – Roel

+1

Các tham số ngược lại: 'image.Load (IDB_PNG1, AfxGetInstanceHandle());' – cwschmidt

2

Nếu bạn không thực sự cần một CBitmap, nhưng chỉ có một tay cầm này có thể hữu ích cho bạn.

Hoặc nếu bạn có thể lấy CBitMap từ HBITMAP, hàm này trả về nó cũng tốt.

Tôi sử dụng nó trên một ứng dụng thương mại và nó hoạt động.

// Based on afxbutton.cpp's static function ButtonLoadBitmap 
HBITMAP __stdcall ButtonLoadBitmap(UINT uiBmpResId) 
{ 
    if (uiBmpResId == 0) 
    { 
     return NULL; 
    } 

    LPCTSTR lpszResourceName = MAKEINTRESOURCE(uiBmpResId); 
    ENSURE(lpszResourceName != NULL); 

    HBITMAP hbmp = NULL; 

    // Try to load PNG image first: 
    CPngImage pngImage; 
    if (pngImage.Load(lpszResourceName)) 
    { 
     hbmp = (HBITMAP) pngImage.Detach(); 
    } 
    else 
    { 
     HINSTANCE hinstRes = AfxFindResourceHandle(lpszResourceName, RT_BITMAP); 
     if (hinstRes == NULL) 
     { 
      return NULL; 
     } 

     UINT uiLoadImageFlags = LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS; 

     hbmp = (HBITMAP) ::LoadImage(hinstRes, lpszResourceName, IMAGE_BITMAP, 0, 0, uiLoadImageFlags); 
    } 

    return hbmp; 
} 
Các vấn đề liên quan