Saving Bitmap image data to HGLOBAL [modified]
-
I made a small change: void* pMyGlobal = GlobalLock(MyHGlobal); UnmanagedMemoryStream^ ms = gcnew UnmanagedMemoryStream((unsigned char*)(pMyGlobal), GlobalSize(gPtrImage)); MyImage->Save(ms, System::Drawing::Imaging::ImageFormat::Bmp); It builds but then I get ExternalException was unhandled in GDI+
alleyes wrote:
It builds but then I get ExternalException was unhandled in GDI+
I can't debug that for you from here, but I suspect not enough allocated on the HGLOBAL. So maybe something like this:
MemoryStream^ ms = gcnew MemoryStream(); MyImage->Save(ms, System::Drawing::Imaging::ImageFormat::Bmp); if (GlobalSize(MyHGlobal) < ms->Length) { GlobalRealloc(MyHGlobal, ms->Length, 0); } void \*pMyGlobalMemory = GlobalLock(MyHGlobal); UnmanagedMemoryStream^ ums = gcnew UnmanagedMemoryStream((unsigned char \*)pMyGlobalMemory, GlobalSize(MyHGlobal)); ms->WriteTo(ums); GlobalUnlock(MyHGlobal);
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
alleyes wrote:
It builds but then I get ExternalException was unhandled in GDI+
I can't debug that for you from here, but I suspect not enough allocated on the HGLOBAL. So maybe something like this:
MemoryStream^ ms = gcnew MemoryStream(); MyImage->Save(ms, System::Drawing::Imaging::ImageFormat::Bmp); if (GlobalSize(MyHGlobal) < ms->Length) { GlobalRealloc(MyHGlobal, ms->Length, 0); } void \*pMyGlobalMemory = GlobalLock(MyHGlobal); UnmanagedMemoryStream^ ums = gcnew UnmanagedMemoryStream((unsigned char \*)pMyGlobalMemory, GlobalSize(MyHGlobal)); ms->WriteTo(ums); GlobalUnlock(MyHGlobal);
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
alleyes wrote:
It builds but then I get ExternalException was unhandled in GDI+
I can't debug that for you from here, but I suspect not enough allocated on the HGLOBAL. So maybe something like this:
MemoryStream^ ms = gcnew MemoryStream(); MyImage->Save(ms, System::Drawing::Imaging::ImageFormat::Bmp); if (GlobalSize(MyHGlobal) < ms->Length) { GlobalRealloc(MyHGlobal, ms->Length, 0); } void \*pMyGlobalMemory = GlobalLock(MyHGlobal); UnmanagedMemoryStream^ ums = gcnew UnmanagedMemoryStream((unsigned char \*)pMyGlobalMemory, GlobalSize(MyHGlobal)); ms->WriteTo(ums); GlobalUnlock(MyHGlobal);
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
NotSupportedException unhandled. Stream does not support writing? Since when? :confused:
Sorry try another constructor: ...gcnew UnmanagedMemoryStream((unsigned char *)pMyGlobalMemory, GlobalSize(MyHGlobal), GlobalSize(MyHGlobal), FileAccess.ReadWrite);
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Sorry try another constructor: ...gcnew UnmanagedMemoryStream((unsigned char *)pMyGlobalMemory, GlobalSize(MyHGlobal), GlobalSize(MyHGlobal), FileAccess.ReadWrite);
Mark Salsbery Microsoft MVP - Visual C++ :java:
Ugh! Still getting an AccessViolation Exception. That can either mean not enough memory available or is that this memory can't be written to. I see the CanWrite, CanSeek flags are TRUE. Capacity and Length are both the same - 1658934
modified on Thursday, January 21, 2010 9:22 AM
-
Ugh! Still getting an AccessViolation Exception. That can either mean not enough memory available or is that this memory can't be written to. I see the CanWrite, CanSeek flags are TRUE. Capacity and Length are both the same - 1658934
modified on Thursday, January 21, 2010 9:22 AM
Did you use FileAccess.ReadWrite? I'm only guessing here since I don't know what line the exception occurs on...
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Did you use FileAccess.ReadWrite? I'm only guessing here since I don't know what line the exception occurs on...
Mark Salsbery Microsoft MVP - Visual C++ :java:
Hi, This is what I have so far:
MemoryStream^ ms = gcnew MemoryStream();
MyImage->Save(ms, System::Drawing::Imaging::ImageFormat::Bmp);
ms->Seek(0, SeekOrigin::Begin);if (GlobalSize(MyGlobal) < ms->Length)
{
GlobalReAlloc(MyGlobal, (LONG)ms->Length, 0);
}void* pMyGlobal = (UCHAR*)MyGlobal;
UnmanagedMemoryStream^ ums = gcnew UnmanagedMemoryStream((UCHAR*)pMyGlobal, GlobalSize(MyGlobal), GlobalSize(MyGlobal), FileAccess::ReadWrite);
ums->Position = 0;
ms->WriteTo(ums);It occurs on the line: ms->WriteTo(ums); This is even without setting the Position of the streams. I did this because just before the Call to WriteTo, the position was set to Length.
-
Hi, This is what I have so far:
MemoryStream^ ms = gcnew MemoryStream();
MyImage->Save(ms, System::Drawing::Imaging::ImageFormat::Bmp);
ms->Seek(0, SeekOrigin::Begin);if (GlobalSize(MyGlobal) < ms->Length)
{
GlobalReAlloc(MyGlobal, (LONG)ms->Length, 0);
}void* pMyGlobal = (UCHAR*)MyGlobal;
UnmanagedMemoryStream^ ums = gcnew UnmanagedMemoryStream((UCHAR*)pMyGlobal, GlobalSize(MyGlobal), GlobalSize(MyGlobal), FileAccess::ReadWrite);
ums->Position = 0;
ms->WriteTo(ums);It occurs on the line: ms->WriteTo(ums); This is even without setting the Position of the streams. I did this because just before the Call to WriteTo, the position was set to Length.
Where did this come from? void* pMyGlobal = (UCHAR*)MyGlobal; Casting a handle to a pointer is bad. For an HGLOBAL it's bad unless you know for sure GMEM_FIXED was used to allocate the memory. Much safer to use GlobalLock to get the pointer.
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Where did this come from? void* pMyGlobal = (UCHAR*)MyGlobal; Casting a handle to a pointer is bad. For an HGLOBAL it's bad unless you know for sure GMEM_FIXED was used to allocate the memory. Much safer to use GlobalLock to get the pointer.
Mark Salsbery Microsoft MVP - Visual C++ :java:
Sorry I threw you there. The lock is already done earlier during the creating of the original images. Didn't make sense to call another GlobalLock on it again. The call to GlobalAlloc is GlobalAlloc(GMEM_MOVEABLE, Size) You have to call GlobalLock on the existing memory again?
-
Sorry I threw you there. The lock is already done earlier during the creating of the original images. Didn't make sense to call another GlobalLock on it again. The call to GlobalAlloc is GlobalAlloc(GMEM_MOVEABLE, Size) You have to call GlobalLock on the existing memory again?
alleyes wrote:
The lock is already done earlier during the creating of the original images. Didn't make sense to call another GlobalLock on it again. The call to GlobalAlloc is GlobalAlloc(GMEM_MOVEABLE, Size)
Then you need to use the pointer returned by the GlobalLock() call.
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Sorry I threw you there. The lock is already done earlier during the creating of the original images. Didn't make sense to call another GlobalLock on it again. The call to GlobalAlloc is GlobalAlloc(GMEM_MOVEABLE, Size) You have to call GlobalLock on the existing memory again?
alleyes wrote:
Didn't make sense to call another GlobalLock on it again.
There's nothing wrong with locking again as long as you have an equal number of unlock calls. GlobalRealloc on a locked handle can only reallocate memory in the same place so has more chance of failing, since there may not be enough room in that place. For best results the handle should be unlocked before reallocating then locked again when you need the pointer.
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
alleyes wrote:
Didn't make sense to call another GlobalLock on it again.
There's nothing wrong with locking again as long as you have an equal number of unlock calls. GlobalRealloc on a locked handle can only reallocate memory in the same place so has more chance of failing, since there may not be enough room in that place. For best results the handle should be unlocked before reallocating then locked again when you need the pointer.
Mark Salsbery Microsoft MVP - Visual C++ :java: