 |
|
 |
I have some bmp pics in res file and also import them into my project. how can I call these bmp pics to fill a rectangle.
using GDI+.
and give a sample better
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
Is this code works with ATL projects.
Requirement is IE toolbar to have a PNG icons instead of ICO.Now It works fine with ICO.I need to make it work for PNG.Any Help??
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I can think of no reason this wouldn't work with ATL.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
|
| Sign In·View Thread·PermaLink | 4.40/5 |
|
|
|
 |
|
|
 |
|
 |
Not sure. I've only used GDI+ to load and display images. For programs that need to manipulate them, I've had access to LeadTools. GDI+ has an Image::Save method, but I've never used it. If you're converting from one bit-per-pixel count to a lower one, you'll need to use some sort of dithering.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
In case you wonder (like I did) if it might be simpler to use CImage along similar lines and avoid GDI+ It indeed works using CImage::Load(IStream*) and the image is displayed. The only catch is that the transparency (alpha channel) info from PNG image is either lost or (most probably) just ignored in CImage. Some articles recommend manually 'pre-multiplying' color values by alpha =) Gdiplus::Bitmap works fine.
P.S. I wonder if it might be a reason why IE did not handle transparent PNGs until recently 
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
Hi,
Nice job I use it on my app with PNG on a dialog: It works fine ! But I notice something when the image is loaded, the size was not the same as the original file, and blured as a redimensionned picture. After a small investigation, I have found that my pictures made with Gimp were scaled in 72 DPI (Dot Per Inch) instead of 96 DPI in native. I scaled them back in 96 DPI, now everything looks find. I didn't try in other format than PNG, and I didn't notice that anybody report a problem about this. Anyway, this can be usefull for anyone that meet this kind of behaviour with images.
Bye. 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
First of all thank you very much for this code... I am trying to change the functionality in order to do something when the button is double clicked and to move the button or the dialog that contains the button when the left button is released, do you think is possible? could you give me some clues? Thanks in advance
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hello, another more question, when the mouse is over the image the image is resized, it’s mean I see two images with different size, do you know which the problem could be? Thank you very much
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Instead of having to copy the resource data to global memory in order to use CreateStreamOnHGlobal, I wrote a simple COM class to allow the image to be loaded directly from the resource data.
//////////////////////////////////////////////////////////////////////////////// // class MEMORY_STREAM // //////////////////////////////////////////////////////////////////////////////// : IStream { ULONG m_ReferenceCount; const PUCHAR m_Memory; ULARGE_INTEGER m_Offset; ULARGE_INTEGER m_Size;
public: MEMORY_STREAM ( const void* Memory, DWORD Size ); // IUnknown STDMETHODIMP QueryInterface ( REFIID InterfaceId, void** Object ); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release();
// ISequentialStream STDMETHODIMP Read ( void* Buffer, ULONG ReadBytes, ULONG* BytesRead ); STDMETHODIMP Write ( const void* Buffer, ULONG WriteBytes, ULONG* BytesWritten );
// IStream
STDMETHODIMP Seek ( LARGE_INTEGER Move, DWORD Origin, ULARGE_INTEGER* NewPosition ); STDMETHODIMP SetSize ( ULARGE_INTEGER NewSize ); STDMETHODIMP CopyTo ( IStream* Stream, ULARGE_INTEGER CopyBytes, ULARGE_INTEGER* BytesRead, ULARGE_INTEGER* BytesWritten ); STDMETHODIMP Commit ( DWORD Flags ); STDMETHODIMP Revert(); STDMETHODIMP LockRegion ( ULARGE_INTEGER Offset, ULARGE_INTEGER Size, DWORD Type ); STDMETHODIMP UnlockRegion ( ULARGE_INTEGER Offset, ULARGE_INTEGER Size, DWORD Type ); STDMETHODIMP Stat ( STATSTG* Stats, DWORD Flag ); STDMETHODIMP Clone ( IStream** Stream ); };
//////////////////////////////////////////////////////////////////////////////// // // MEMORY_STREAM Implementation // ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// // STDMETHODCALLTYPE MEMORY_STREAM::MEMORY_STREAM ( const void* Image, DWORD Size ) // //////////////////////////////////////////////////////////////////////////////// : m_ReferenceCount(0), m_Memory((PUCHAR)Image) { m_Offset.QuadPart = 0; m_Size.QuadPart = Size; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP_(ULONG) MEMORY_STREAM::AddRef() // //////////////////////////////////////////////////////////////////////////////// { return ++m_ReferenceCount; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP_(ULONG) MEMORY_STREAM::Release() // //////////////////////////////////////////////////////////////////////////////// { ULONG ReferenceCount(--m_ReferenceCount); if (m_ReferenceCount == 0) { delete this; }
return ReferenceCount; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::QueryInterface ( REFIID InterfaceId, void** Object ) // //////////////////////////////////////////////////////////////////////////////// { while (true) { if (IsEqualGUID(InterfaceId, __uuidof(IUnknown))) { *Object = static_cast<IUnknown*>(this); break; }
if (IsEqualGUID(InterfaceId, __uuidof(IStream))) { *Object = static_cast<IStream*>(this); break; }
*Object = NULL; return E_NOINTERFACE; }
AddRef(); return S_OK; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::Read ( void* Buffer, ULONG ReadBytes, ULONG* BytesRead ) // //////////////////////////////////////////////////////////////////////////////// { ULONG Length; HRESULT Result;
if (m_Offset.QuadPart + ReadBytes > m_Size.QuadPart) { Length = (ULONG)(m_Size.QuadPart - m_Offset.QuadPart); Result = S_FALSE; } else { Length = ReadBytes; Result = S_OK; } CopyMemory(Buffer, m_Memory + (ULONG_PTR)m_Offset.QuadPart, Length); m_Offset.QuadPart += Length;
if (BytesRead) { *BytesRead = Length; }
return Result; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::Write ( const void* Buffer, ULONG WriteBytes, ULONG* BytesWritten ) // //////////////////////////////////////////////////////////////////////////////// { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::Seek ( LARGE_INTEGER Move, DWORD Origin, ULARGE_INTEGER* NewPosition ) // //////////////////////////////////////////////////////////////////////////////// { switch (Origin) { case STREAM_SEEK_SET: m_Offset.QuadPart = Move.QuadPart; break; case STREAM_SEEK_CUR: if (m_Offset.QuadPart + Move.QuadPart > m_Size.QuadPart) { return STG_E_INVALIDFUNCTION; } m_Offset.QuadPart += Move.QuadPart; break; case STREAM_SEEK_END: if ((ULONGLONG)Move.QuadPart > m_Offset.QuadPart) { return STG_E_INVALIDFUNCTION; } m_Offset.QuadPart = m_Size.QuadPart - Move.QuadPart; break; default: return STG_E_INVALIDFUNCTION; } if (NewPosition) { *NewPosition = m_Offset; }
return S_OK; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::SetSize ( ULARGE_INTEGER NewSize ) { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::CopyTo ( IStream* Stream, ULARGE_INTEGER CopyBytes, ULARGE_INTEGER* BytesRead, ULARGE_INTEGER* BytesWritten ) // //////////////////////////////////////////////////////////////////////////////// { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::Commit ( DWORD Flags ) { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::Revert() { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::LockRegion ( ULARGE_INTEGER Offset, ULARGE_INTEGER Size, DWORD Type ) // //////////////////////////////////////////////////////////////////////////////// { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::UnlockRegion ( ULARGE_INTEGER Offset, ULARGE_INTEGER Size, DWORD Type ) // //////////////////////////////////////////////////////////////////////////////// { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::Stat ( STATSTG* Stats, DWORD Flags ) // //////////////////////////////////////////////////////////////////////////////// { ZeroMemory(Stats, sizeof(*Stats));
if ((Flags & STATFLAG_NONAME) != STATFLAG_NONAME) { Stats->pwcsName = (LPOLESTR)CoTaskMemAlloc(sizeof(OLECHAR)); if (Stats->pwcsName) { *Stats->pwcsName = 0; } } Stats->type = STGTY_STREAM; Stats->cbSize = m_Size; return S_OK; }
//////////////////////////////////////////////////////////////////////////////// // STDMETHODIMP MEMORY_STREAM::Clone ( IStream** Stream ) // //////////////////////////////////////////////////////////////////////////////// { return E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////// // HRESULT CreateStreamOnResource ( HMODULE Instance, PCTSTR Type, PCTSTR Name, IStream** Stream ) // //////////////////////////////////////////////////////////////////////////////// { HRSRC ResourceHandle = FindResource(Instance, Name, Type);
if (ResourceHandle) { DWORD Size = ::SizeofResource(Instance, ResourceHandle);
if (Size) { HGLOBAL Resource = LoadResource(Instance, ResourceHandle);
if (Resource) { const void* Data = LockResource(Resource); MEMORY_STREAM* MemoryStream = new MEMORY_STREAM(Data, Size); if (!MemoryStream) { return E_OUTOFMEMORY; } return MemoryStream->QueryInterface ( __uuidof(IStream), (void**)Stream ); } } }
return HRESULT_FROM_WIN32(GetLastError()); }
You can then use the class like this to create a GDI+ bitmap:
IStream* Stream; Bitmap* bitmap(NULL);
if ( CreateStreamOnResource ( Instance, _T("PNG"), MAKEINTRESOURCE(IDI_IMAGE), &Stream ) == S_OK ) { bitmap = Gdiplus::Bitmap::FromStream(Stream); Stream->Release(); }
Nick Acquaviva
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I like it.
This could be an article.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
I appreciate feedback, but I find your comments useless without any explanation as to why you are making your assertions. Please explain how Release() is a bug. According to all the documentation I have seen, the Release() is proper.
You statement about try and catch make no sense. You do understand that IStream is part of windows structured storage, not STL.
If you want to have exceptions thrown, you may modify the code for your benefit.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thanks for your reply.
The testing like this Begin another thread and load resource image in thread function (could sleep(100) once for a while), then pop up a simple modal dialog with an edit box, you could see when you press the edit box it will display rubbish data, then press editbox another time, crash!
The problem seems about CreateStreamOnHGlobal, I made second parameter FALSE, then it's ok HRESULT hResult = ::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream);
HGLOBAL hBuffer = NULL;
try { // get resource from PNG HRSRC hResource = ::FindResource(hInst, MAKEINTRESOURCE(nResourcId), pType); if (!hResource) throw int();
// get size of read resource DWORD dwSize = ::SizeofResource(hInst, hResource); if (!dwSize) throw int(); // allocate memory to store data hBuffer = ::GlobalAlloc(GMEM_FIXED, dwSize);
// put data into HGLOBAL HGLOBAL hGresource = ::LoadResource(hInst, hResource); if (!hGresource) throw int();
// copy data into buffer void *pData = ::LockResource(hGresource); memcpy((void*)hBuffer, pData, dwSize);
// convert data into stream LPSTREAM pStream; HRESULT hResult = ::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream); if (hResult != S_OK) throw int();
// convert data into Bitmap m_pbmPicture = Gdiplus::Bitmap::FromStream(pStream); bResult = TRUE; pStream->Release();
// release buffer ::GlobalFree(hBuffer); } catch (...) // on error: release memory { if (hBuffer) { ::GlobalFree(hBuffer); }
if (m_pbmPicture != NULL) { delete m_pbmPicture; m_pbmPicture = NULL; } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,I'm not an expert, just want to find the problem,
The reason maybe complicated, i just testing your demo(2008) and find no crash, since my project using 2002 I'm not sure if project environment is different.
The testing result is either I change HRESULT hResult = ::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream); then lpStream->Release(); it's ok or I remove lpStream->Release(); , keep HRESULT hResult = CreateStreamOnHGlobal(hBuffer, TRUE, &lpStream);, also ok.
BTW, english is not my first language, sorry for any impolite
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I really find this to be cool if wrapped in a user control, could you help me port it into C# ?
"Imagination is more important than knowledge.." {Albert Einstein}
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
No, since this isn't an issue in .NET.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
All this inherited object stuff was looking a bit complicated to me so I've re-written this code (thanks very much for it BTW!) in a single function. It seems to work but please let me know if you spot anything wrong with what I've done as I'm new to GDIplus.
Bitmap* pToolbar; pToolbar = LoadPNG("TOOLBAR", RT_RCDATA, hInstance);
delete pToolbar
Bitmap* LoadPNG(LPCTSTR pName, LPCTSTR pType, HMODULE hInstance) { HGLOBAL hBuffer; Bitmap* pBitmap;
HRSRC hResource = ::FindResource(hInstance, pName, pType); if (!hResource) { return NULL; }
DWORD dwImageSize = ::SizeofResource(hInstance, hResource); if (!dwImageSize) { return NULL; }
const void* pResourceData = ::LockResource(::LoadResource(hInstance, hResource)); if (!pResourceData) { return NULL; }
hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, dwImageSize); if (hBuffer) { void* pBuffer = ::GlobalLock(hBuffer);
if (pBuffer) { CopyMemory(pBuffer, pResourceData, dwImageSize);
IStream* pStream = NULL; if (::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) == S_OK) { pBitmap = Gdiplus::Bitmap::FromStream(pStream); pStream->Release();
if (pBitmap) { if (pBitmap->GetLastStatus() == Gdiplus::Ok) { ::GlobalUnlock(hBuffer); ::GlobalFree(hBuffer); return pBitmap; }
delete pBitmap; } }
::GlobalUnlock(hBuffer); }
::GlobalFree(hBuffer); }
return NULL; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Your version will fail on success with those files (particularly JPG) which require that the global buffer remain valid while the bitmap object is being used.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Ahhh, I hadn't realised that! Personally I only need this code for loading PNG files though so I guess I'm OK?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Sean O'Connor wrote: so I guess I'm OK?
I think so; it appears that PNG's decompress right away. Of course, the test is whether you have any problems.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |