c++ - How to construct a GDI+ Bitmap object from a Device-Dependent HBITMAP -


i want use gdi+ method image::save() save ddb file in following scenario:

hbitmap hbitmap = createcompatiblebitmap(hdc, 200, 200) ;  ...  //hbitmap ddb need pass hpalette gdiplus::bitmap(hbitmap,  ???hpalette???  ).save(l"file.png", ...) ; 

the problem bitmap constructor asks hpalette when bitmap not device-independent bitmap.

where necessary hpalette from?


followup:
1 of answers suggests passing null hpalette parameter.
here working example so. result purely black , white image colors lost.

#include <windows.h> #include <gdiplus.h>  int main(){     using namespace gdiplus ;      gdiplusstartupinput gdiplusstartupinput ;     ulong_ptr gdiplustoken ;     gdiplusstartup(&gdiplustoken, &gdiplusstartupinput, null) ;      clsid pngencoder = {0x557cf406, 0x1a04, 0x11d3, {0x9a, 0x73, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} } ;      hdc dchndl = createcompatibledc(null) ;      hbitmap hbitmap = createcompatiblebitmap(dchndl, 200, 200) ;      selectobject(dchndl, hbitmap) ;      bitblt(dchndl, 0,0, 200,200, getdc(null), 0,0, srccopy|captureblt) ;      bitmap(hbitmap, null).save(l"file.png", &pngencoder) ; } 

as createcompatiblebitmap remarks sate if dealing color bitmaps can assume hdc nonmemory device context (because memory device context create monochrome bitmaps) , color palette used bitmap same color palette used device context. can query using getcurrentobject method. remarks bitmap.bitmap(hbitmap, hpalette) constructor state:

do not pass gdi+ bitmap::bitmap constructor gdi bitmap or gdi palette (or previously) selected device context.

so can not used current device context palette directly , need create copy of instead.

/// <returns> /// handle palette selected device context without granting ownership. /// </returns> _check_return_ ::hpalette fetch_currentpalette(_in_ ::hdc const h_dc) {     assert(h_dc);     ::hgdiobj const h_palette_object{::getcurrentobject(h_dc, obj_pal)}; // not owned     assert(h_palette_object);     assert(obj_pal == ::getobjecttype(h_palette_object));     //  perform unchecked conversion of generic gdi object descriptor gdi palette descriptor.     ::hpalette h_current_palette{}; // not owned     {         static_assert(sizeof(h_palette_object) == sizeof(h_current_palette), "wat");         ::memcpy         (             ::std::addressof(h_current_palette)         ,   ::std::addressof(h_palette_object)         ,   sizeof(h_current_palette)         );     }     return(h_current_palette); }  /// <returns> /// handle palette copy granting ownership. /// </returns> _check_return_ ::hpalette make_palettecopy(_in_ ::hpalette const h_palette) {     assert(h_palette);     ::uint const first_entry_index{};     ::uint entries_count{};     ::lppaletteentry p_entries{};     //  figure out how many entries palette contains.     entries_count = ::getpaletteentries(h_palette, first_entry_index, entries_count, p_entries);     assert(1 < entries_count);     assert(entries_count <= ::std::numeric_limits< decltype(logpalette::palnumentries) >::max());     //  buffer hold palette description contains first paletteentry last field.     //  followed rest of paletteentry items.     ::std::unique_ptr< ::std::uint8_t[] > const p_buffer     {         new ::std::uint8_t[sizeof(::logpalette) + (sizeof(::paletteentry) * (entries_count - 1u))]     };     //  perform unchecked conversion of buffer pointer palette description pointer.     ::logpalette * p_description{};     {         ::std::uint8_t * const p_buffer_bytes{p_buffer.get()};         static_assert(sizeof(p_buffer_bytes) == sizeof(p_description), "wat");         ::memcpy         (             ::std::addressof(p_description)         ,   ::std::addressof(p_buffer_bytes)         ,   sizeof(p_description)         );     }     //  copy palette entries buffer.     p_entries = static_cast< ::lppaletteentry >(p_description->palpalentry);     ::uint const copied_entries_count     {         ::getpaletteentries(h_palette, first_entry_index, entries_count, p_entries)     };     assert(copied_entries_count == entries_count);     //  create palette copy.     p_description->palversion = 0x300; // magic     p_description->palnumentries = static_cast< ::word >(copied_entries_count);     ::hpalette const h_copied_palette{::createpalette(p_description)}; // owned     assert(h_copied_palette);     return(h_copied_palette); }    ::hpalette const hpal{make_palettecopy(fetch_currentpalette(hdc))}; // owned assert(hpal); ::hbitmap const hbitmap{::createcompatiblebitmap(hdc, 200, 200)}; // owned assert(hbitmap); {     ::gdiplus::bitmap bmp{hbitmap, hpal};     assert(::gdiplus::status::ok == bmp.getlaststatus());     //  something... } //  delete palette , bitmap after gdi+ bitmap object went out of scope. if(false == ::deleteobject(hpal)) {     assert(false); } if(false == ::deleteobject(hbitmap)) {     assert(false); } 

Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -