link

Dear Debuggers, I have the following code fragment (and variants on it) -- it uses a COM P/Invoke to retrieve an out string pVal of size out int pSize which is actually a reference to a block of memory (24bit Colo(u)r) which I am attempting to write into a pictureBox (i.e. System.IntPtr Scan0 = bmData.Scan0;) for near real-time display. Unfortunately, the code comes in a Managed Ref which I don't know how to "Cast" directly so that I could (in C++ style) point the Scan0 pointer at it. Furthermore, the image (in GDI+) is upside down (8 bit byte wise) -- so requires a second loop to get it rightside up. This isn't particularly fast in C# -- and while I do require the data be byte readable (for other image processing purposes) -- I wonder whether there's a quicker way to get the pVal pointed at and retained by the Scan0?


(from the DLL metadata) void ReadBuffer(out int pSize, out string pVal);

public void PreviewBuffer()
{
int pSize;
string pVal;
global.MyCameraController.ImageStream.ReadBuffer(out pSize, out pVal);

Bitmap b = (Bitmap)global.MyForm.pictureBoxPreview.Image;

BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;

unsafe
{
byte* p = (byte*)(void*)Scan0;
Int16* ip = (Int16*)p;
int nOffset = stride - b.Width * 3;

for (int i = 0; i < pSize / 2; i++)
{
ip[i] = (Int16)pVal[i];
}

byte* p1 = p + ((b.Width * b.Height * 3) - (b.Width * 3));
for (int y = 0; y < b.Height / 2; y++)
{
for (int x = 0; x < b.Width * 3; x++)
{
byte temp = p[x];
p[x] = p1[x];
p1[x] = temp;
}
p += b.Width * 3;
p1 -= b.Width * 3;
}
}

b.UnlockBits(bmData);
pictureBoxPreview.Invalidate();
}

As an aside, the "other path" I "see this image stream" through is via a COM Interop Call which sends a pictureBoxLive.Handle directly into the COM DLL which then handles the handle directly. This is much faster -- and am also wondering whether there may be a way to "pass a dummy handle" with a double adapter (on the recieving managed side) to sneak the data out (into the original window and another I need to blend with a seperate semi-transparent image).

global.MyCameraController.LockDevice(1000);
global.MyCameraController.ImageStream.Format = EnumFormat.FormatRGB;
global.MyCameraController.ImageStream.Window = (int)pictureBoxLive.Handle;
global.MyCameraController.ImageStream.Start(DSCAMERALib.EnumRender.RenderBufferAndWindow);
IsLive = true;

Finally, I have considered the option of trying to draw a "truely transparent" pictureBox with the second image I need to overlay over either the COM invoked PictureBoxLive (which alas, doesn't seem to talk to OnPaint -- as well as the GDI+ issues with transparency) -- or perhaps a final attempt to render a transparent (Alpha Channel) pictureBox over my second ReadBuffer pictureBox (the one referenced at the top). Alas, I am having no joy with transparancy except between applicationss. Basically, we have a Microscope with a Microled Array Image that needs to be calibrated and overlayed on top of the Live Feed from the Microscope Camera to see where the Microleds are illuminating the Neurons. The max res is 2560x1920x24bit and the Microled is about 10%-20% of the Field of View with a selection of a 64x64 Led Array switched on at any one point.