2011-01-04 16 views
10

मेरे पास एक ऐसा एप्लिकेशन है जो डेटाबेस से कुछ ब्लॉब डेटा लोड करता है जो विभिन्न बिटमैप और आइकन के लिए पीएनजी स्वरूपित या कच्चे बाइनरी डेटा का प्रतिनिधित्व कर सकता है। यह एक std::vector<unsigned char>मेमोरी बफर से HBITMAP बनाना

में संग्रहित किया जा रहा है मैं पेड़ विचारों में विभिन्न छवियों, उपकरण पट्टी चित्र, आदि प्रदर्शित करने के लिए CImageList वस्तुओं का उपयोग कर रहा हूँ, लेकिन समस्या स्मृति में डेटा से बिटमैप पैदा कर रही है फजी बाहर आ रहे हैं जैसे कि वह पिक्सल जब याद आ रही है नीचे की तरह कुछ कर रही:

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

अब मैं बस बाहर डेटा() वेक्टर में एक अस्थायी फ़ाइल के लिए लिख रहा हूँ और फिर LoadImage का उपयोग कर इसे में वापस पढ़ने के लिए और कहा कि से HBITMAP बनाने के लिए इस मुद्दे को हल करने के लिए । यह पूरी तरह से काम करता है हालांकि यह स्वीकार्य रूप से एक लापरवाही हैक है और मुझे पूरी तरह से अनावश्यक होना चाहिए।

मैंने ऑनलाइन चारों ओर देखा है लेकिन मेमोरी से "ठीक से" बनाने के तरीके के बारे में कोई भी अच्छा उदाहरण नहीं मिला है। मैं छवि सूची में किसी भी फ़ाइल I/o के बिना इन बिटमैप्स को जोड़ने के लिए सक्षम होना चाहता हूं और यदि संभव हो तो डेटा को कॉपी करने की सीमित मात्रा।

ऐसा करने का सबसे अच्छा तरीका खोज रहे हैं और स्पष्ट रूप से विंडोज़ विशिष्ट कोड ठीक है।

अद्यतन:

jdv का जवाब मैं CreateCompatibleBitmap, CreateDIBitmap, और अंत में CreateDIBSection साथ खेलना शुरू किया पर आधारित है। इनमें से सभी पिछले अस्पष्ट बिटमैप्स की बजाय सुंदर ब्लैक बिटमैप्स बना रहे हैं, इसलिए मुझे फिर से कुछ गलत करना होगा और मेरा अनुमान है क्योंकि इस बिटमैप निर्माण को उस ऑब्जेक्ट में किया जा रहा है जिसमें स्क्रीन डीसी या विंडो की कोई अवधारणा नहीं है जो 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) का उपयोग कर रहा हूं। std::vector<unsigned char> से CBitmap ऑब्जेक्ट को प्रारंभ करने के लिए किसी को भी एक आसान तरीका पता है?

+0

प्रति बदल गया है कृपया एक नया अर्थ के लिए प्रश्न को संपादित नहीं करते के रूप में यह जवाब अमान्य हो जाएगा। एक नया प्रश्न पोस्ट करने और पुराने को लिंक करने के लिए स्वतंत्र महसूस करें। –

+0

क्षमा करें बस एक कदम वापस ले लिया और महसूस किया कि मैं जीडीआई भूमि में जा रहा था क्योंकि एकमात्र कारण था क्योंकि मैं सीमैजलिस्ट में जोड़ते समय FromHandle विधि का उपयोग कर रहा था ... एमएफसी सीबीआईटीमैप बस जीडीआई कॉल को लपेटता है, इसलिए यह बहुत समान है। – AJG85

उत्तर

3

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

संपादित करें: Jegatheesh

+1

और 'Gdiplus :: बिटमैप *' से एचबीआईटीएमएपी कैसे प्राप्त करें? –

5

मैं CreateCompatibleBitmap का उपयोग करता हूं, और फिर अपने डेटा के साथ भरने के लिए SetDIBits पर कॉल करता हूं। ये वे कार्य हैं जिन्हें मैंने काम करने के लिए देखा है, और SetDIBits काफी लचीला है, हालांकि वर्बोज़।

मेरे एमएफसी वर्षों में, CreateBitmap संदिग्ध प्रदर्शन समस्याओं के कारण टाला गया था।

+1

मैं अब CreateDIBitmap को देख रहा हूं, जो मैं मूल रूप से डीसी संगत बिटमैप बनाता हूं और फिर यदि आप CBM_INIT ध्वज निर्दिष्ट करते हैं तो SetDIBits के बराबर कॉल करता है। विंडोज एपीआई में जो भी पैरामीटर और structs के सदस्यों का नाम दिया जाना चाहिए शॉट करने की जरूरत है। – AJG85

+0

ओह, ठीक है, CreateDIBitmap भी था। –

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