UnlockBits releases my Byte-Array
-
Hello, is there any way, that the UnlockBits-Method doesn't release my byte-pointer, when I created an image from it? The byte-pointer, that I give to the Bitmapdata Scan0 value, is contains always after the "UnlockBits"-Method an . But I have to do further operations on that pointer. Is there a way to keep track of that pointer or am I doing something wrong? Tanks in advance, cherry
-
Hello, is there any way, that the UnlockBits-Method doesn't release my byte-pointer, when I created an image from it? The byte-pointer, that I give to the Bitmapdata Scan0 value, is contains always after the "UnlockBits"-Method an . But I have to do further operations on that pointer. Is there a way to keep track of that pointer or am I doing something wrong? Tanks in advance, cherry
stop using the pointer after calling UnlockBits, or postpone calling UnlockBits until you're done with the pointer. FWIW: When passing a data pointer to some native code, I prefer using the GCHandle class. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
stop using the pointer after calling UnlockBits, or postpone calling UnlockBits until you're done with the pointer. FWIW: When passing a data pointer to some native code, I prefer using the GCHandle class. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
Thanks so far, I describe my problem a little bit more exactly: As soon as my camera has taken a new picture, I get a BYTE- (or char)-pointer of it. This happens in unmanaged code, but it's no problem to delegate it to managed. Now I create my bitmap like that: myBitmapData = myImage->LockBits(*myRect,WriteOnly,Format8bppIndexed); myBitmapData->Scan0 = myBytePtr; myBitmapData->Stride = iImageWidth*iImagePlanes; myImage->UnlockBits(myBitmapData); The final call of UnlockBits makes my BYTE pointer to an undefined value, so if this Function is called again (and it has to be called again to define the new Bitmap) without a new Image was taken, the function gets an empty pointer and crashes. Is there no possibility to keep that pointer? Or would anyone of you even create that bitmap some other way? I'm not sure if this method is a good one... I'd be happy for some hints! Thanks
-
Thanks so far, I describe my problem a little bit more exactly: As soon as my camera has taken a new picture, I get a BYTE- (or char)-pointer of it. This happens in unmanaged code, but it's no problem to delegate it to managed. Now I create my bitmap like that: myBitmapData = myImage->LockBits(*myRect,WriteOnly,Format8bppIndexed); myBitmapData->Scan0 = myBytePtr; myBitmapData->Stride = iImageWidth*iImagePlanes; myImage->UnlockBits(myBitmapData); The final call of UnlockBits makes my BYTE pointer to an undefined value, so if this Function is called again (and it has to be called again to define the new Bitmap) without a new Image was taken, the function gets an empty pointer and crashes. Is there no possibility to keep that pointer? Or would anyone of you even create that bitmap some other way? I'm not sure if this method is a good one... I'd be happy for some hints! Thanks
Hi, 1. whatever pointer operations you want to do to the pixels need to be done in between the LockBits and the UnlockBits. 2. do you have to have the native code allocate the data buffer? if yes, there is no way around copying all the pixels into the managed image, which is an expensive and unproductive operation. If no, allocating a managed buffer (could be with new Bitmap and LockBits) and passing the pointer to the native world might eliminate the need for a copy operation. What is the native code you are using? out of curiosity: what is the make and model of your camera? :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
Hello, is there any way, that the UnlockBits-Method doesn't release my byte-pointer, when I created an image from it? The byte-pointer, that I give to the Bitmapdata Scan0 value, is contains always after the "UnlockBits"-Method an . But I have to do further operations on that pointer. Is there a way to keep track of that pointer or am I doing something wrong? Tanks in advance, cherry
Also, if you want to keep a pointer to the pixel bits around, use the Bitmap constructor that takes an IntPtr. If you pass a pointer to a pre-allocated array, you can use that pointer until the array is freed, and you don't need to use LockBits to access it (although in multithread situations you may need to synchronize access to it). Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Hello, is there any way, that the UnlockBits-Method doesn't release my byte-pointer, when I created an image from it? The byte-pointer, that I give to the Bitmapdata Scan0 value, is contains always after the "UnlockBits"-Method an . But I have to do further operations on that pointer. Is there a way to keep track of that pointer or am I doing something wrong? Tanks in advance, cherry
Here's an example of what I'm talking about:
public ref class Form1 : public System::Windows::Forms::Form { unsigned char \*pBitmapBits; Bitmap ^testBitmap; public: Form1(void) { InitializeComponent(); // Make a 120x120 24bpp bitmap - initialize pixels to all red pBitmapBits = new unsigned char\[120 \* 120 \* 3\]; for (int x = 0; x < (120\*120\*3); x += 3) { pBitmapBits\[x+0\] = 0; pBitmapBits\[x+1\] = 0; pBitmapBits\[x+2\] = 255; } testBitmap = gcnew Bitmap(120, 120, 120\*3, PixelFormat::Format24bppRgb, IntPtr(pBitmapBits)); }
...
private: System::Void testButton\_Click(System::Object^ sender, System::EventArgs^ e) { // Put a purple stripe across the bitmap for (int x = 120\*3\*40; x < (120\*3\*80); x += 3) { pBitmapBits\[x+0\] = 255; pBitmapBits\[x+1\] = 0; pBitmapBits\[x+2\] = 255; } // Render the bitmap so we can see the results Graphics ^g = this->CreateGraphics(); g->DrawImage(testBitmap, 10, 10); }
};
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Here's an example of what I'm talking about:
public ref class Form1 : public System::Windows::Forms::Form { unsigned char \*pBitmapBits; Bitmap ^testBitmap; public: Form1(void) { InitializeComponent(); // Make a 120x120 24bpp bitmap - initialize pixels to all red pBitmapBits = new unsigned char\[120 \* 120 \* 3\]; for (int x = 0; x < (120\*120\*3); x += 3) { pBitmapBits\[x+0\] = 0; pBitmapBits\[x+1\] = 0; pBitmapBits\[x+2\] = 255; } testBitmap = gcnew Bitmap(120, 120, 120\*3, PixelFormat::Format24bppRgb, IntPtr(pBitmapBits)); }
...
private: System::Void testButton\_Click(System::Object^ sender, System::EventArgs^ e) { // Put a purple stripe across the bitmap for (int x = 120\*3\*40; x < (120\*3\*80); x += 3) { pBitmapBits\[x+0\] = 255; pBitmapBits\[x+1\] = 0; pBitmapBits\[x+2\] = 255; } // Render the bitmap so we can see the results Graphics ^g = this->CreateGraphics(); g->DrawImage(testBitmap, 10, 10); }
};
Mark Salsbery Microsoft MVP - Visual C++ :java:
Thanks a lot you people! I'm very happy of always getting such good answers. Respect, for me you are number #1 in the web! On Topic: I'll test your way to create bitmap tomorrow, it's late in europe right now ;-) It looks good, but I remember some problems as I wanted to get it done like that. The cam I use is a monochrome Leutron PicSight P52M-USB, and the only way I get monochrome Bitmaps done is to assign the Format8bppIndexed - which further made some problems in resizing, so that I have to work with a temp-Image. I'm not happy with that, but I didn't get a better way yet. I'd be more happy with not having to work with marshaling between managed and unmanaged. But my company has "old" native interfaces (one for graphic, one for cam), which must not be changed. So I had to delegate all function (the way I got it done is also from codeproject) - but it seems to me as a not very stable solution, to call a managed GUI in creating a thread from native and so on... Maybe someone wonders about an odd comment, please let me know. I may be on the wrong way somewhere... Thanks again for your time, bye!