Bitmap Constructor IntPtr issue
Alright, so I have image data in a buffer and that is what I want to be the bitmap that displays on the screen. Would I still use LockBits() for that?Here is what I have...and note that I have done about 30 renditions of this so it is very likely something could be off. I keep getting errors that the last value, temp, in the Bitmap constructor call cannot be converted from int to IntPt. I also am a little confused in using the Marshal::Copy method. To me this takes the unmanaged data.buffer information and copies that into the managed array (temp). However, after I do the Marshal::Copy, I need to update the temp array still using data from the unmanaged buffer. Is that safe or can that mess up the temp array?
cannot convert parameter 5 from 'cli::array<Type,dimension> ^' to 'System::IntPtr'
with
[
Type=System::IntPtr,
dimension=1
]
array<IntPtr>^ temp=gcnew array<IntPtr>(width*height);
Marshal::Copy((IntPtr)&Data.buffer, temp, 0, width*height);
for(int i=0; i < (width*height);i++)
{
unsigned short bufValue = Data.buffer;
bufValue = bufValue >> 6;
temp = IntPtr(bufValue);
}
Bitmap^ bitMap2 = gcnew Bitmap(width,height, width*4, Imaging:ixelFormat::Format32bppRgb, temp);
pictureBox1->Image = bitMap2;
[1390 byte] By [
LizAgain] at [2008-1-10]
The last parameter to the Bitmap constructor is
scan0
Pointer to an array of bytes that contains the pixel data.
and that's what you have to provide; you can't just provide an arbitrary value and *say* it's a pointer to the bytes. The address of a handle to a managed array of int's isn't even close.
You should also think carefully about what
temp = bufValue;
does compared to what you actually want to do.
Sdi at 2007-10-3 >

I am glad there are smart people out there to point out this kind of stuff...
Here is what I changed and it actually 'appears' like the image data is being displayed except it's all diagonal lines but when I move the source of the images around, the display changes so I know it's at least coming from the source.
BYTE my_array[WIDTH*HEIGHT];
for(int i=0; i < (WIDTH*HEIGHT);i++)
{
my_array
=(0x010101)*(HSIData.buffer
>> 6);
}
bitMap = gcnew Bitmap(WIDTH, HEIGHT, 4, PixelFormat::Format32bppRgb, IntPtr(my_array));
pictureBox1->Image = bitMap;
My next question is about the stride in the Bitmap call, which right now I have set to 4 because if I actually have it equal to WIDTH*4 I get the same error as before. This doesn't make sense to me because the definition is this:
stride:
Integer that specifies the byte offset between the beginning of one scan line and the next. This is usually (but not necessarily) the number of bytes in the pixel format (for example, 2 for 16 bits per pixel) multiplied by the width of the bitmap. The value passed to this parameter must be a multiple of four.
"An unhandled exception of type 'System.AccessViolationException' occurred in System.Drawing.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Are there more stride rules that I am unaware of? Thanks for your assistance.
The 'stride' is dependent on the format of the bitmap. Say, for example, your bitmap is WIDTH pixels wide (height is irrelevant to the 'stride' discussion) and is formatted as Format8bppIndexed. Then the width of each scan line is
(WIDTH * 8) / sizeof(BYTE) = WIDTH
OK, that's fairly trivial. But if your pixel format was Format1bppIndexed instead and your bitmap was 23 pixels wide, each scan line would be
((23 * 1) + 7) / 8 = 3
bytes wide, with the last bit of the last byte being ignored. But 3 is an "illegal" value; like the API says, 'stride' has to be a multiple of 4 bytes, so you'd have to 'pad' each scan line out so that it was 32 bits wide, giving a 'stride' of 4. For the 'legal' 1bpp/23-pixel-wide bitmap, each scan line would contain 23 bits of real data and 9 bits of padding; the padding is completely ignored, so you can set it to whatever you like.
So, if your pixel format has at least 8 bits per pixel, 'stride' is simply (bits per pixel * pixel width) / 8. If your format has less than 8 bits per pixel, you may have to 'pad' each scan line out to an even multiple of 32 bits wide.
Sdi at 2007-10-3 >
