Getting the webcam image onto an XNA screen

Aug 27, 2009 at 1:24 PM
Edited Aug 27, 2009 at 1:29 PM

Hi

I'm trying to get a webcam feed onto the XNA drawn form that doesn't have a picturebox control on it to invoke the paint method on. I was trying spriteBatch.Draw but I'm getting no error and no change in my display. Code is refusing to paste in, but its basically the Form_Load from the walkthrough section

JSynnott - it looks like one of your samples on http://www.jsynnott.com/tag/microsoft-touchless/ may have done exactly what I need, so if you can help would be appreciate - love the game demo btw

Thanks

Andrew

Aug 27, 2009 at 2:48 PM

c&p doesn't work for me in this editor here, too, but clicking the html-button, adding a <pre></pre> tag and inserting the code inside this tag works fine :)

Aug 28, 2009 at 1:29 PM

Unfortuantly the same doesn't work for me, thanks though. I can see a numbr of people have done this with directshow, only one example with touchless so far. I think its just drawing it onto a 2d texture but I'm not doing so well with that....

Oct 21, 2009 at 3:12 PM

Hi guys, I've just done this exact thing. I played around for a while and managed to display the image from the camera in XNA and have the image moved around by the marker.

I took a screenshot of the marker, saved it as a bitmap, and I load that as marker 0.

Here's the code:

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using TouchlessLib;
using System.Drawing;

namespace TouchlessGame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {        
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        TouchlessMgr touchMan;
        Sprite sprite;
        Texture2D camImage;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            touchMan = new TouchlessMgr();
            foreach (Camera c in touchMan.Cameras)
            {
                if (c != null)
                {
                    touchMan.CurrentCamera = c;
                    break;
                }
            }
            camImage = new Texture2D(GraphicsDevice, touchMan.CurrentCamera.CaptureWidth, touchMan.CurrentCamera.CaptureHeight);
            touchMan.CurrentCamera.OnImageCaptured += new EventHandler<CameraEventArgs>(CurrentCamera_OnImageCaptured);
            sprite = new Sprite();

            base.Initialize();
        }

        void CurrentCamera_OnImageCaptured(object sender, CameraEventArgs e)
        {
            camImage = TextureFromBitmap(e.Image);
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
            Bitmap b = new Bitmap(@"D:\glowstick.bmp");
            touchMan.AddMarker("glowstick", b, new System.Drawing.Point(10, 10), 20);
            touchMan.Markers[0].Highlight = true;
            touchMan.Markers[0].SmoothingEnabled = true;
            touchMan.Markers[0].Threshold = 15;
            Console.WriteLine(touchMan.MarkerCount.ToString());
            //sprite.LoadContent(this.Content, "front");
            sprite.SetContent(camImage);
            sprite.Position = new Vector2(100, 200);

        }

        private Texture2D TextureFromBitmap(Bitmap bmp)
        {
            Texture2D tx = null;
            using (System.IO.MemoryStream s = new System.IO.MemoryStream())
            {
                bmp.Save(s, System.Drawing.Imaging.ImageFormat.Png);
                s.Seek(0, System.IO.SeekOrigin.Begin);
                tx = Texture2D.FromFile(GraphicsDevice, s);
            }
            return tx;
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            
            sprite.Position = new Vector2((float)touchMan.Markers[0].LastGoodData.X * 2, (float)touchMan.Markers[0].LastGoodData.Y * 2);
            sprite.SetContent(camImage);

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            sprite.Draw(this.spriteBatch);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

And here's the Sprite class. I only used this because it was in some tutorial I was looking at.. I modified it a bit by adding the SetContent method.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace TouchlessGame
{
    class Sprite
    {
        //The current position of the Sprite
        public Vector2 Position = new Vector2(0, 0);

        //The texture object used when drawing the sprite
        private Texture2D mSpriteTexture;

        public void LoadContent(ContentManager theContentManager, string assetName)
        {
            mSpriteTexture = theContentManager.Load<Texture2D>(assetName);
        }

        public void SetContent(Texture2D tx)
        {
            mSpriteTexture = tx;
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(mSpriteTexture, Position, Color.White);
        }
    }
}
Oct 10, 2010 at 12:11 PM

Flyteuk I noticed in yours you are using TouchlessLib. I was just wondering what reference I need to include to use this

Oct 14, 2010 at 2:30 AM

Sameone else got a problem work with following method:



 private Texture2D TextureFromBitmap(Bitmap bmp)
        {
            Texture2D tx = null;
            using (System.IO.MemoryStream s = new System.IO.MemoryStream())
            {
                bmp.Save(s, System.Drawing.Imaging.ImageFormat.Png);
                s.Seek(0, System.IO.SeekOrigin.Begin);
                tx = Texture2D.FromFile(GraphicsDevice, s);
            }
            return tx;
        }

The webcam it showed in the XNA but the fot a LAG in all the timeon movie, i would like remove LAG's sameone can help me?

At windowsform the lag doesnt happen.