2008-12-02 9 views
7

जब मैं बिटमैप :: FromHBITMAP फ़ंक्शन का उपयोग करके एक नया Gdiplus :: बिटमैप बनाता हूं, परिणामी बिटमैप अपारदर्शी है - मूल एचबीआईटीएमएपी से आंशिक पारदर्शिता में से कोई भी संरक्षित नहीं है।एक एचडीआईटीएमएपी से बिटमैप कैसे बनाएं, अल्फा चैनल जानकारी को बनाए रखें?

क्या एचडीआईटीएमएपी से जीडीप्लस :: बिटमैप बनाने का कोई तरीका है जो अल्फा चैनल डेटा में लाता है?

+0

क्या आप वाकई HBITMAP अल्फ़ा चैनल के साथ शुरू करने के लिए है कि के लिए पता है? उदाहरण के लिए, क्या आपने इसे BI_RGB और 32bpp या किसी अन्य तरीके से डीआईबी के रूप में बनाया है? –

+0

हां, इसमें पारदर्शिता है। यह :: अल्फाब्लेंड() फ़ंक्शन का उपयोग करके अच्छी तरह से आकर्षित करता है। – mackenir

+0

(मैंने इसे नए बिटमैप (स्ट्रिंग फ़ाइल नाम) और .NET बिटमैप ऑब्जेक्ट पर GetHBitmap() को कॉल करके सी # में बनाया है। – mackenir

उत्तर

4

यह पता चला है कि एक एचबीआईटीएमएपी से बिटमैप बनाते समय जीडीआई + अल्फा चैनल में कभी नहीं लाता है।

जवाब देने के लिए है:

  • उपयोग GetObject एक बिटमैप और HBITMAP में गुजर, चौड़ाई और ऊंचाई पाने के लिए (और यदि इनपुट बिटमैप एक डीआईबी, पिक्सेल डेटा है) इनपुट HBITMAP की।
  • 32 बिट PARGB पिक्सेल प्रारूप के साथ सही आकार का बिटमैप बनाएं।
  • अपने नए बिटमैप की पिक्सेलडेटा मेमोरी को पकड़ने के लिए लॉकबिट का उपयोग करें।
  • यदि आपको GetObject से पिक्सेल मिलते हैं, तो memcpy का उपयोग करके ARGB मानों की प्रतिलिपि बनाएँ।
  • नए बिटमैप पर अनलॉक बिट्स पर कॉल करें।

मेरे मामले में, इनपुट एचबीआईटीएमएपी का प्रारूप इनपुट बिटमैप पिक्सेल डेटा से सीधे बिटमैप पिक्सेल डेटा में सीधे memcpy करने के लिए सही है।

यदि आपको GetObject से इनपुट पिक्सेल डेटा नहीं मिला है, तो सही प्रारूप में प्रतिलिपि प्राप्त करने के लिए GetDIBits का उपयोग करें।

9

मैं काम कर लगता है कि कोड निर्देश की तुलना में अधिक उपयोगी है, इसलिए:

#include <GdiPlus.h> 
#include <memory> 

Gdiplus::Status HBitmapToBitmap(HBITMAP source, Gdiplus::PixelFormat pixel_format, Gdiplus::Bitmap** result_out) 
{ 
    BITMAP source_info = { 0 }; 
    if(!::GetObject(source, sizeof(source_info), &source_info)) 
    return Gdiplus::GenericError; 

    Gdiplus::Status s; 

    std::auto_ptr<Gdiplus::Bitmap> target(new Gdiplus::Bitmap(source_info.bmWidth, source_info.bmHeight, pixel_format)); 
    if(!target.get()) 
    return Gdiplus::OutOfMemory; 
    if((s = target->GetLastStatus()) != Gdiplus::Ok) 
    return s; 

    Gdiplus::BitmapData target_info; 
    Gdiplus::Rect rect(0, 0, source_info.bmWidth, source_info.bmHeight); 

    s = target->LockBits(&rect, Gdiplus::ImageLockModeWrite, pixel_format, &target_info); 
    if(s != Gdiplus::Ok) 
    return s; 

    if(target_info.Stride != source_info.bmWidthBytes) 
    return Gdiplus::InvalidParameter; // pixel_format is wrong! 

    CopyMemory(target_info.Scan0, source_info.bmBits, source_info.bmWidthBytes * source_info.bmHeight); 

    s = target->UnlockBits(&target_info); 
    if(s != Gdiplus::Ok) 
    return s; 

    *result_out = target.release(); 

    return Gdiplus::Ok; 
} 
+0

मुझे 'सीबीआईटीएमएपी 'के साथ समान समस्या थी, जिसमें से मैंने' एचबीआईटीएमएपी 'पुनर्प्राप्त किया था। उस स्थिति में ':: GetObject()' left 'source_info.bmBits' को पूर्ण पर सेट करें। मैं 'myCBitmapPtr-> GetBitmapBits (source_info.bmWidthBytes * source_info.bmHeight, target_info.Scan0) ' – foraidt

+0

बीटीडब्लू को कॉल करके इसे हल कर सकता हूं, वापसी मान आपके उदाहरण में अच्छी तरह से चेक किए जाते हैं, लेकिन यदि' source_info.bmBits' शून्य है, तो वहां पहुंच है 'CopyMemory() 'पर कॉल में उल्लंघन। – foraidt

संबंधित मुद्दे