2

In my windows application I use Windows Media Player dlls to play a video.

In my form I have a button to take a picture of the current video frame.

I did a lot of tests and code examinations but I couldn't find out why taking a picture of the current frame fails.

I tried this code, but the resulting image was black:

private Graphics g = null;

private void btnTakePicture_Click(object sender, EventArgs e)
{
    if (!string.IsNullOrEmpty(axWMVMovie.URL))
    {
        axWMVMovie.Ctlcontrols.pause();
        if (saveFileDialog1.ShowDialog() == DialogResult.OK)
        {
            System.Drawing.Image ret = null;
            try
            {
                Bitmap bitmap = new Bitmap(axWMVMovie.Width, axWMVMovie.Height);
                {
                    g = Graphics.FromImage(bitmap);
                    {
                        Graphics gg = axWMVMovie.CreateGraphics();
                        {
                            timerTakePicFromVideo.Start();
                        }
                    }

                    using (MemoryStream ms = new MemoryStream())
                    {
                        bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                        ret = System.Drawing.Image.FromStream(ms);
                        ret.Save(saveFileDialog1.FileName);
                    }
                }
            }
            catch
            {
            }
        }
    }
}

private void timerTakePicFromVideo_Tick(object sender, EventArgs e)
{
    timerTakePicFromVideo.Stop();

    g.CopyFromScreen(axWMVMovie.PointToScreen(new System.Drawing.Point()).X, 

    axWMVMovie.PointToScreen(new System.Drawing.Point()).Y, 0, 0,

    new System.Drawing.Size(axWMVMovie.Width, axWMVMovie.Height));
}

I use Timer because when the user selects the save path, function takes image from the file user specified in save file dialog. Video format is WMV.

Toon Krijthe
  • 52,876
  • 38
  • 145
  • 202
Hajitsu
  • 764
  • 17
  • 49
  • 1
    Why are you using a *timer to take a pic from a video*? In my opinion your tick_event code will be executed after your bitmap has been created. Did you try moving `g.CopyFromScreen(..)` to `btnTakePicture_Click(..)`? – Pilgerstorfer Franz Oct 08 '12 at 07:28
  • +1. The calls inside the curly brackets (that don't do anything, e.g. to `timerTakePicFromVideo.Start();`) are bizarre. – tomfanning Oct 08 '12 at 07:37
  • @PilgerstorferFranz i use timer beacuse when user select address of save, until the savedialog closed, image take and savedialog image was saved – Hajitsu Oct 08 '12 at 07:53
  • this [pic](http://tinypic.com/view.php?pic=24zm0s3&s=6) is a pic i don't use timer. background image in savedialogfile is video – Hajitsu Oct 08 '12 at 08:03

2 Answers2

4

I took your code and modified it. I put the code to capture the photo a little bit up and now it works. I create the picture right before the saveFileDialog pops up, so you will really get only the picture and not the saveFileDialog within your pic.

if (!string.IsNullOrEmpty(axWindowsMediaPlayer1.URL))
{
    axWindowsMediaPlayer1.Ctlcontrols.pause();

    System.Drawing.Image ret = null;
    try
    {
        // take picture BEFORE saveFileDialog pops up!!
        Bitmap bitmap = new Bitmap(axWindowsMediaPlayer1.Width, axWindowsMediaPlayer1.Height);
        {
            Graphics g = Graphics.FromImage(bitmap);
            {
                Graphics gg = axWindowsMediaPlayer1.CreateGraphics();
                {
                    //timerTakePicFromVideo.Start();
                    this.BringToFront();
                    g.CopyFromScreen(
                        axWindowsMediaPlayer1.PointToScreen(
                            new System.Drawing.Point()).X,
                        axWindowsMediaPlayer1.PointToScreen(
                            new System.Drawing.Point()).Y,
                        0, 0,
                        new System.Drawing.Size(
                            axWindowsMediaPlayer1.Width,
                            axWindowsMediaPlayer1.Height)
                        );
                }
            }
            // afterwards save bitmap file if user wants to
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                    ret = System.Drawing.Image.FromStream(ms);
                    ret.Save(saveFileDialog1.FileName);
                }
            }
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
}
Pilgerstorfer Franz
  • 8,303
  • 3
  • 41
  • 54
1

With previous answer a trick to avoid getting the controls on the capture is to do this before you capture :

string uimode_previus = axWindowsMediaPlayer2.uiMode;
axWindowsMediaPlayer2.uiMode = "none";

then when capture is done set the uimode back to previous like this :

axWindowsMediaPlayer2.uiMode = uimode_previus ;

In that way you only get the actual shoot from the current frame. it is a little workaround but it does the job.

Here is working example

private void button8_Click_1(object sender, EventArgs e)
{
  string uimode_previus = axWindowsMediaPlayer2.uiMode;
  axWindowsMediaPlayer2.uiMode = "none";

  if (!string.IsNullOrEmpty(axWindowsMediaPlayer2.URL))
  {
    ret = null;
    try
    {
      // take picture BEFORE saveFileDialog pops up!!
      Bitmap bitmap = new Bitmap(axWindowsMediaPlayer2.Width, axWindowsMediaPlayer2.Height);
      {
        Graphics g = Graphics.FromImage(bitmap);
        {
          Graphics gg = axWindowsMediaPlayer2.CreateGraphics();
          {
            //timerTakePicFromVideo.Start();
            this.BringToFront();
            g.CopyFromScreen(axWindowsMediaPlayer2.PointToScreen(
                             new System.Drawing.Point()).X,
                             axWindowsMediaPlayer2.PointToScreen(
                             new System.Drawing.Point()).Y,
                             0, 0,
                             new System.Drawing.Size(
                             axWindowsMediaPlayer2.Width - 0,
                             axWindowsMediaPlayer2.Height - 0)
                            );
          }
        }
        // afterwards save bitmap file if user wants to
        try
        {
          using (MemoryStream ms = new MemoryStream())
          {
            string rute = axWindowsMediaPlayer2.URL.ToString().Replace(".", "Review_."); // 
            bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            ret = new Bitmap(System.Drawing.Image.FromStream(ms));
            ret.Save(rute.Replace(".mp4", ".Png"));
          }

          // open captured frame in new form
          TeamEasy.ShowPictureForm spf = new ShowPictureForm();
          spf.ImagePictureBox.Image = ret;
          spf.ShowDialog();
        }
        catch (Exception ex)
        {
          Debug.WriteLine(ex.Message);
        }
      }
    }
    catch (Exception ex)
    {
      Debug.WriteLine(ex.Message);
    }
  }

  axWindowsMediaPlayer2.uiMode = uimode_previus;
  // restore the UImode of player
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225