|
Mark Salsbery wrote: I can't debug that for you from here
No of course not.
I was suspecting perhaps an image already in memory was the issue and maybe that needed a dispose method called, not sure.
Thanks for the re-size tip
|
|
|
|
|
NotSupportedException unhandled.
Stream does not support writing?
Since when?
|
|
|
|
|
Sorry try another constructor:
...gcnew UnmanagedMemoryStream((unsigned char *)pMyGlobalMemory, GlobalSize(MyHGlobal), GlobalSize(MyHGlobal), FileAccess.ReadWrite);
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
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++
|
|
|
|
|
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++
|
|
|
|
|
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++
|
|
|
|
|
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++
|
|
|
|
|
Sincere thanks Mark
When I have the time, I think I'll do all this in managed code by Marshalling the native HGLOBAL. But for now it works well.
|
|
|
|
|
I know that I can create from scratch the BITMAPINFOHEADER. Is it a matter of copying the information to the top of the Bitmap array?
|
|
|
|
|
alleyes wrote: Is it a matter of copying the information to the top of the Bitmap array?
If that's where you want it, yes.
You could also start with a pointer to where you want it
so you don't have to copy afterwards...
BITMAPINFOHEADER *pbmiHeader = (BITMAPINFOHEADER *)GlobalLock(myhglobal);
pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
etc...
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: If that's where you want it, yes.
Well actually the file header will be at top but I get it.
Mark Salsbery wrote: BITMAPINFOHEADER *pbmiHeader = (BITMAPINFOHEADER *)GlobalLock(myhglobal);
pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
That's helpful...
|
|
|
|
|
After searching on the internet, the possible solution that come out is by using TabPage.DrawToBitmap, put the bitmap in a PictureBox, set the position of PictureBox to the same location of TabPage, and fade it. The code is below :
System::Void tabControl1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
{
alphaBlend = 250;
repaint = true;
TabPictureBox->Visible = true;
int posX = tabControl1->Location.X + tabControl1->TabPages[tabControl1->SelectedIndex]->Margin.Left + 1;
int posY = tabControl1->Location.Y + tabControl1->ItemSize.Height + 1 +
tabControl1->TabPages[tabControl1->SelectedIndex]->Margin.Top;
TabPictureBox->Location = System::Drawing::Point(posX, posY);
TabPictureBox->Size = tabControl1->TabPages[tabControl1->SelectedIndex]->Size;
TabBitmap = gcnew Bitmap(tabControl1->TabPages[tabControl1->SelectedIndex]->Width,
tabControl1->TabPages[tabControl1->SelectedIndex]->Height);
tabControl1->TabPages[tabControl1->SelectedIndex]->DrawToBitmap(TabBitmap,
Rectangle(0, 0, tabControl1->TabPages[tabControl1->SelectedIndex]->Width,
tabControl1->TabPages[tabControl1->SelectedIndex]->Height));
while (alphaBlend > 0)
{
alphaBlend = alphaBlend - 25;
TabPictureBox->Refresh();
}
TabPictureBox->Visible = false;
repaint = false;
}
System::Void TabPictureBox_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e)
{
if (repaint)
{
if (TabBitmap != nullptr)
{
Bitmap^ temp = gcnew Bitmap(TabBitmap);
Graphics^ bitmapGraphics = Graphics::FromImage(temp);
if (alphaBlend < 0) alphaBlend = 0;
SolidBrush^ greyBrush = gcnew SolidBrush(Color::FromArgb(alphaBlend, Color::White));
bitmapGraphics->CompositingMode = CompositingMode::SourceOver;
bitmapGraphics->FillRectangle(greyBrush, Rectangle(0, 0, TabBitmap->Width, TabBitmap->Height));
e->Graphics->CompositingQuality = CompositingQuality::GammaCorrected;
e->Graphics->DrawImage(temp, 0, 0);
}
}
}
The problem is that each time I select the tabPage, my CPU usage spike to 70 - 80% and the fading effect is kind of slow. Is there any solution to fix it so that I can draw the bitmap faster and with minimum CPU usage (less than 50%)?
Thanks.
|
|
|
|
|
I need a program in PHP which can extract the hidden biders from ebay.I will have to insert the item number and the program must show me all bidders of the auction and their emails.
Also the same program must extract the registered contact information for any specified bidder specially the email address
I will pay for this
If someone can help please contact me at totos_back@yahoo.com
Thanks
|
|
|
|
|
In an app that is used to capture images, the information used to store the image data is referenced by a pointer to HGLOBAL. That is then used to re-create the image so it can be written to disk with a call to GlobalFree.
I have two problems:
I need to attach a file header so I can write the image to a file.
The image data is of native type DWORD so I cant use the .NET classes without massaging the image data.
What I have done thus far:
BITMAPINFOHEADER* imgHeader = (BITMAPINFOHEADER*)GlobalLock(gPtrImage);
array<BYTE>^ imgArray = gcnew array<BYTE>(imgHeader->biSizeImage);
if (!imgHeader)
{
GlobalFree(gPtrImage);
return;
}
BITMAPFILEHEADER* bfh = new BITMAPFILEHEADER();
bfh->bfType = 0x4d42; //BM
bfh->bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + imgHeader->biSize + imgHeader->biSizeImage);
bfh->bfReserved1 = 0;
bfh->bfReserved2 = 0;
bfh->bfOffBits = (DWORD) (bfh->bfSize - imgHeader->biSizeImage);
LPDWORD Pixels = (LPDWORD)((LPBYTE)imgHeader + sizeof(BITMAPINFOHEADER));
Marshal::Copy(static_cast<IntPtr>(bfh), imgArray, 0, sizeof(BITMAPFILEHEADER));
Marshal::Copy(static_cast<IntPtr>(Pixels), imgArray, (sizeof(BITMAPFILEHEADER) + 1), imgHeader->biSizeImage);
GlobalUnlock(gPtrImage);
System::Environment::SpecialFolder saveFolder = System::Environment::SpecialFolder::MyDocuments;
SaveFileDialog^ sfd = gcnew SaveFileDialog();
sfd->InitialDirectory = System::Environment::GetFolderPath(saveFolder);
sfd->Filter = "Device Independent Bitmaps |*.bmp|All files|*.*";
if (sfd->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
System::IO::Stream^ imgFileStream = sfd->OpenFile();
if (imgFileStream != nullptr)
{
imgFileStream->Write(imgArray, 0, imgArray->Length);
imgFileStream->Close();
}
}
GlobalFree(gPtrImage);
gPtrImage = NULL;
The file size is a lot larger than I would expect for a 640*480 32 bit BMP and it can't be displayed.
The image is fine when written to a picturebox, the data is then unlocked but NOT freed. As a test, I save the image of the picturebox i.e PictureBox->Image and that is fine. The data needs to to be handed off to another application that requires native code so I need to re-create the image from the pointer to HGLOBAL and that's where it falls down
What might be wrong with this?
Thanks for any help
|
|
|
|
|
BITMAPINFOHEADER.biSizeImage is allowed to be 0...
I would personally feel better about checking for that unless
you know for sure it's never going to be 0...maybe something like
if (imgHeader->biSizeImage == 0)
imgHeader->biSizeImage = (((imgHeader->biWidth * (long)imgHeader->biBitCount + 31L) & (~31L)) / 8L) * abs(imgHeader->biHeight);
Al_S wrote: array<BYTE>^ imgArray = gcnew array<BYTE>(imgHeader->biSizeImage);
Your array isn't big enough. What about the size of the
BITMAPFILEHEADER and the BITMAPINFOHEADER?
Al_S wrote: Marshal::Copy(static_cast<intptr>(Pixels), imgArray, (sizeof(BITMAPFILEHEADER) + 1), imgHeader->biSizeImage);
Array indexes are 0-based... That should be
Marshal::Copy(static_cast<intptr>(Pixels), imgArray, sizeof(BITMAPFILEHEADER), imgHeader->biSizeImage);
Also I'm not sure about those static_casts... why not just use IntPtr(bfh)/IntPtr(Pixels)
Al_S wrote: The file size is a lot larger than I would expect for a 640*480 32 bit BMP
Should be a little over 1MB - just how big is it? You're the one
calculating the size - what do you see in the debugger?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi Mark.
Since the original image is from a global pointer to HGLOBAL, which was previously created and displayed, I am aware of all the fields of the BITMAPINFOHEADER. They are all set from grabbing an image in other code. I am trying to re-create the image after handing off the pointer to HGLOBAL elsewhere
With that:
biSizeImage = 0x12c000 (about 1.2M)
biBitCount = 0x20
...
...
I saw that the array size was goofy so I fixed that - I think.
array<byte>^ imgArray = gcnew array<byte>(imgHeader->biSizeImage + sizeof(BITMAPFILEHEADER));
I also fixed copying to the array:
Marshal::Copy(static_cast<IntPtr>(bfh), imgArray, 0, sizeof(BITMAPFILEHEADER));
Marshal::Copy(static_cast<IntPtr>(Pixels), imgArray, sizeof(BITMAPFILEHEADER), imgHeader->biSizeImage);
All this washes out to a correct file size.
When viewed in a hex editor, the BITMAPFILEHEADER appears where it belongs correctly. The rest of the data is different though. The resultant image can not be viewed
As far as the use of the static_cast, I don't have any problems with that and I think I've used it properly.
Thanks for responding.
|
|
|
|
|
alleyes wrote: I saw that the array size was goofy so I fixed that - I think.
array^ imgArray = gcnew array<BYTE>(imgHeader->biSizeImage + sizeof(BITMAPFILEHEADER));
Still not big enough
array<BYTE>^ imgArray = gcnew array<BYTE>(imgHeader->biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
alleyes wrote: Marshal::Copy(static_cast<IntPtr>(Pixels), imgArray, sizeof(BITMAPFILEHEADER), imgHeader->biSizeImage);
You're not writing the BITMAPINFOHEADER to the output array...
I missed that one the first time, sorry
Marshal::Copy(static_cast<IntPtr>(imgHeader), imgArray, sizeof(BITMAPFILEHEADER), sizeof(BITMAPINFOHEADER) + imgHeader->biSizeImage);
Mark Salsbery
Microsoft MVP - Visual C++
modified on Tuesday, January 12, 2010 4:47 PM
|
|
|
|
|
array size change plus the proper copy nails it.
Thanks very much!
|
|
|
|
|
Hi Mark,
Is there a way to do the reverse of this?
That is, one HGLOBAL to store different images, where it normally is one HGLOBAL relating to one image.
Thanks for the valuable help!
|
|
|
|
|
Hi Developers.
i am going to wrap lib(static library ) file in c++. one function return HGLOBAL DIB. how can i access Byte Array or Bitmap Image from this and pass this Byte Array or bitmap to My C# Project.
please help me.
thanks in advance.
Here is function that return HGLOBAL DIB Type.
<pre lang="c++"> HGLOBAL m_hDib;
int retval = XRaySensorIsImageAvailable();
if ( 0 < retval )
{
if (m_hDib ) ::GlobalFree(m_hDib);
m_hDib = XRaySensorGetDIB();
}
|
|
|
|
|
Hi
How can i get the screen width and height in Managed C++/CLI? I have used
Screen^ screen = gcnew Screen::PrimaryScreen;
But its not working.
Thanks
|
|
|
|
|
Within the Screen class, PrimaryScreen is a property, not a constructor. So you don't need gcnew
FYI1: "its not working" is not informative; if there is an error or exception, best is to show us the message.
FYI2: all this is explained in the documentation. Maybe it would be wise to study an introductory book when getting acquainted to a new technology or language.
|
|
|
|