GetBitmapImage

Apr 19, 2010 at 6:49 AM
Edited Apr 19, 2010 at 8:29 AM

Hi, 

in the user manual I read about a function called GetBitmapImage() for DirectShowCapture but it's not available in version 3.4.
Is there a function with which I get the current captured image? GetImageTextrue() works fine but it only for integer array which contains only the RGB product of each pixel and I need the color. 

How to use imagePtr?
I tried following but get a empty img: 

IntPtr img = new IntPtr();         
captureDevice.GetImageTexture(curImg, ref img);

Thank you!

Coordinator
Apr 30, 2010 at 12:07 AM

Hi,

Sorry for delayed reply.

The user manual had the old function call for DirectShowCapture, and it doesn't have GetBitmapImage() function anymore.

The best way to do this is actually changing the code of DirectShowCapture.cs in GoblinXNA, and recompile it.

1. Add the following lines in the member field of the class:

 

public delegate bool ImageReadyCallback(IntPtr image, int[] background);
private ImageReadyCallback imageReadyCallback;

 

2. Add the following lines under the property list:

 

public ImageReadyCallback Callback
{
    set { imageReadyCallback = value; }
}

 

3. Replace (Marsha.Copy(grabbedImage, ....)) line with the following codes in GetImageTexture function:

 

bool replaceBackground = false;
if (imageReadyCallback != null)
    replaceBackground = imageReadyCallback(grabbedImage, returnImage);

if(!replaceBackground)
    Marshal.Copy(grabbedImage, returnImage, 0, returnImage.Length);

 

Now, in your code, add the following code:

((DirectShowCapture)captureDevice).Callback = delegate(IntPtr image, int[] background)
{
    // set this true if you want to replace the current background video image by assigning 'background' parameter
    bool replaceBackground = false;

    // do whatever you like with the image pointer which contains the information of the grabbed video image
    // Note that you will need to use unsafe code to access the RGB data in the memory address
    // For DirectShowCapture, the pixel order of the grabbed image is left to right, and down to top

    return replaceBackground;
}

This callback function will be called whenever it updates the background video image.

This lets you access the captured image as well as assign your own background video image (for example, a gray-scaled video image converted from the original RGB image). This change will be included in v3.5 release, but for now, please modify the GoblinXNA as mentioned above and recompile it.

 

Ohan

May 6, 2010 at 1:12 AM

Thank you! Works fine for me now.  If I want to flip the captured image horizontal, where is the best place to add a function?

Coordinator
May 9, 2010 at 1:30 PM

Flipping of the image has two issues based on what you want to do.

If you simply flip the rendering of the image horizontally, then the overlaid tracking result from the marker tracker will not match the rendered background image, so you will have to flip the pixels that are passed to the marker tracking library as well (you need to change DirectShowCapture's GetTextureImage function to do this). 

If you don't care about the marker tracking, but simply want to flip the image, then fill 'background' pixels in horizontally flipped order in 

((DirectShowCapture)captureDevice).Callback = delegate(IntPtr image, int[] background)
{
    // set this true if you want to replace the current background video image by assigning 'background' parameter
    bool replaceBackground = false;

    // do whatever you like with the image pointer which contains the information of the grabbed video image
    // Note that you will need to use unsafe code to access the RGB data in the memory address
    // For DirectShowCapture, the pixel order of the grabbed image is left to right, and down to top

    return replaceBackground;
}

Make sure to set replaceBackground to true in that case.

If you want to flip the image and also have the marker tracking show correct result, the best thing to do is to use your camera software to perform the flipping.

Ohan

May 10, 2010 at 4:19 AM

Thanks again! 

I inserted following code and I'm able to flip the screen easily now. 

((DirectShowCapture2)captureDevice).Callback = delegate(IntPtr image, int[] background)
            {
                // set this true if you want to replace the current background video image by assigning 'background' parameter
                bool replaceBackground = true;
		
                if (flipHorizontal)
                {
                    unsafe
                    {
                        int* imgPtr = (int*)image;
                        for (int i = 0; i < captureDevice.Height; i++)
                        {
                            for (int j = 1; j <= captureDevice.Width; j++)
                            {
                                background[captureDevice.Width - j + i * captureDevice.Width] = *imgPtr++;
                            }
                        }                       
                    }
                }
                else
                {
                    unsafe
                    {
                        int* imgPtr = (int*)image;
                        for (int i = 0; i < captureDevice.Height; i++)
                        {
                            for (int j = 0; j < captureDevice.Width; j++)
                            {
                                background[j + i * captureDevice.Width] = *imgPtr++;
                            }
                        }
                    }
                }
                ........
                return replaceBackground;
         };