Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to create ONVIF IP camera snapshot as a JPG image file using C#.NET

0.00/5 (No votes)
15 Oct 2014 1  
I’ll show briefly how to take an ONVIF IP camera snapshot and save this image as a JPG file by using C# to be able to preserve/share the most important moments of the video surveillance.

Table of Contents

Introduction

Getting started

1. ONVIF SDK installation

2. Creating a Windows Forms Application in Visual Studio

The back end development

The front end development (GUI)

Conclusion

References

Introduction

While testing my previous IP camera project (How to Create a Video Recording Application - NVR/DVR software - for an ONVIF IP Camera using C#.NET), it’s occurred to me that the archiving of events can be carried out not only with video recording, but snapshots would be also useful in a security system.

Probably the best way to store all the things what happened in the area that is under video surveillance, if you record the audio and video stream into a video file. In this case you can track each moment – even retrospectively. However, in many cases a picture is worth than any long video. Let’s take a simple but drastic example, which illustrates well the significance of snapshots.

Let’s assume that a burglary has happened and the security camera have recorded the entire offense including the offender's face as well. In order to catch the culprit, it's needed to publish his/her face in different places. A video can not be glued on the trees and a long video file can not be published among the police news in the TV. So there's a definitely need for a snapshot that shows the offender's face.

Although the previous example presented a case when you can take a snapshot by using a prerecorded video, but there is also an existing need for taking snapshots in real time, too. So in this tutorial I’m intended to show you how to build an application in C# that allows you to take an ONVIF IP camera snapshot in real time and save it automatically on your PC. Let’s assume that you or your security staff monitors continuously the security cameras. Due to this functionality, any of your security staff can take a snapshot about any unusual event efficiently. This picture (as a form of evidence) can be easily transmitted to the superiors e.g. via e-mail so that the necessary intervention can be taken immediately.

This project's also based on the ONVIF IP-based security standardization. In this tip, I don’t want to go into details related to ONVIF again. You can read more about the ONVIF technology in my previous article:

C# IP Camera Snapshot Taker Application – Source: Self made

Getting started

After studying the significance of snapshots in surveillance systems, it’s time to start the implementation of your IP camera project. For creating the snapshot taker application, you’ll need (1) an ONVIF SDK and (2) and IDE for C# programming. Let’s see what you need to do to get ready for programming.

1. ONVIF SDK installation

In my previous tutorials (Broadcasting live IP camera stream to website in C# and Creating a video recorder software for cameras in C#) you could read in more details that there is a need for an IP camera SDK if you want to build any IP camera software. For this purpose I used Ozeki’s Camera SDK this time too. You can download the SDK from its official website.

2. Creating a Windows Forms Application in Visual Studio

Similarly to my previous projects, I used Microsoft Visual Studio as an IDE for this project as well. If you need this software, you can download it from the official website of Microsoft. (As far as I know, .NET Framework will be installed automatically with the Visual Studio, but make sure that its 4.0 version has been installed on your PC.)

After you’ve installed all the necessary software, let’s start programming by creating a new Windows Forms Application. After this you need to add the DLL file (provided by the Camera SDK) as a reference to your project. And the only one setting you need to do:  make sure that your ’Target framework’ is ’.NET Framework 4.0’.

Having done all the necessary initial steps, let's do the interpretation of code.

The back end development

For better understanding I’d like to start my code explanation with a brief source code analysis. The following three classes will be presented in this tip:

  • Program.cs
  • Form1.cs
  • Form1.Designer.cs

Let’s take a look at the Program.cs class more closely (see the following code example). This class contains the Main() method that is the entry point for the application .The running of the Form will be called in this class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace Network_Video_Recorder02
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

In case of the camera video recorder application it was also needed to connect your application to your camera to be able to view its image. It’s a really important step, because it's essentially needed to display the camera image if you want to take a snapshot about it. Below you can see those methods that can be used to establish connection between your application and the camera:

_camera = IPCameraFactory.GetCamera("192.168.115.198:8080", "admin", "admin") // It initializes the camera that has been declared as a private member of the class. Three arguments are used: the IP address of the camera, username and password.
_connector.Connect(_camera.VideoChannel, _imageProvider) // Using this method you can create connection between the camera image and the image provider object (that is used to display the camera image on the GUI).
_camera.Start() // It can be used to receive the camera image.
_videoViewerWF1.Start(): // It can be used to display the camera image on the GUI.

In addition to the methods belonging to the camera-application connection, you’ll need some further statements and methods to be able to take snapshots. You can see them below:

button_SaveTo_Click() // This method allows the user to define a path and save the result into the TextBox GUI element.
Btn_Snapshot_Click() // It initializes the path variable that is used to determine the destination folder of the taken image. After this it calls the CreateSnapShot() method.
CreateSnapShot() // This method creates a string that contains the actual date and time then uses these parameters to complete the path. Finally, takes a snapshot about the current camera image and saves it into the destination folder.

By default, if the TextBox GUI element is empty (that's, any path, where the program can save the snapshot to, hasn’t been specified), the captured camera image will be saved to the source folder where the application has been started.

Okay, now let’s take a look at the full Form1.cs class that contains all functions of the application that is needed for taking IP camera snapshots (see the following code example).

using System;
using System.Drawing;
using System.Windows.Forms;
using Ozeki.Media.IPCamera;
using Ozeki.Media.MediaHandlers.Video;
using Ozeki.Media.Video.Controls;
using Ozeki.Media.MediaHandlers;

namespace Network_Video_Recorder02
{
    public partial class Form1 : Form
    {
        private IIPCamera _camera;
        private DrawingImageProvider _imageProvider;
        private MediaConnector _connector;
        private VideoViewerWF _videoViewerWf;
        private SnapshotHandler _snapshotHandler;

        public Form1()
        {
            InitializeComponent();
            _imageProvider = new DrawingImageProvider();
            _connector = new MediaConnector();
            _snapshotHandler = new SnapshotHandler();
            _videoViewerWf = new VideoViewerWF();
            SetVideoViewer();
        }

        private void SetVideoViewer()
        {
            CameraBox.Controls.Add(_videoViewerWf);
            _videoViewerWf.Size = new Size(260, 180);
            _videoViewerWf.BackColor = Color.Black;
            _videoViewerWf.TabStop = false;
            _videoViewerWf.Location = new Point(14, 19);
            _videoViewerWf.Name = "_videoViewerWf";
        }

        private void button_Connect_Click(object sender, EventArgs e)
        {
            _camera = IPCameraFactory.GetCamera("192.168.115.98:8080", "admin", "admin");
            _connector.Connect(_camera.VideoChannel, _imageProvider);
            _connector.Connect(_camera.VideoChannel, _snapshotHandler);
            _videoViewerWf.SetImageProvider(_imageProvider);
            _videoViewerWf.Start();
            _camera.Start();
        }

        private void button_SaveTo_Click(object sender, EventArgs e)
        {
            var result = folderBrowserDialog1.ShowDialog();
            if (result == DialogResult.OK)
                TextBox_SaveTo.Text = folderBrowserDialog1.SelectedPath;
        }

        private void Btn_Snapshot_Click(object sender, EventArgs e)
        {
            var path = TextBox_SaveTo.Text;
            CreateSnapShot(path);
        }

        private void CreateSnapShot(string path)
        {
            var date = DateTime.Now.Year + "y-" + DateTime.Now.Month + "m-" + DateTime.Now.Day + "d-" +
                       DateTime.Now.Hour + "h-" + DateTime.Now.Minute + "m-" + DateTime.Now.Second + "s";
            string currentpath;
            if (String.IsNullOrEmpty(path))
                currentpath = date + ".jpg";
            else
                currentpath = path + "\\" + date + ".jpg";

            var snapShotImage = _snapshotHandler.TakeSnapshot().ToImage();
            snapShotImage.Save(currentpath, System.Drawing.Imaging.ImageFormat.Jpeg);
        }
    }
}

The front end development (GUI)

After you’ve implemented the back end development, let’s move on to the Graphical User Interface. The following code presents the whole Form1.Designer.cs class that contains all elements that is needed for the GUI. This code can be used to create a simple GUI for your snapshot taker application:

namespace Network_Video_Recorder02
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.button_Connect = new System.Windows.Forms.Button();
            this.CameraBox = new System.Windows.Forms.GroupBox();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.TextBox_SaveTo = new System.Windows.Forms.TextBox();
            this.Btn_Snapshot = new System.Windows.Forms.Button();
            this.button_SaveTo1 = new System.Windows.Forms.Button();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            this.SuspendLayout();
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.button_Connect);
            this.groupBox1.Location = new System.Drawing.Point(10, 10);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(120, 60);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Connect";
            // 
            // button_Connect
            // 
            this.button_Connect.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
            this.button_Connect.ForeColor = System.Drawing.Color.Black;
            this.button_Connect.Location = new System.Drawing.Point(10, 20);
            this.button_Connect.Name = "button_Connect";
            this.button_Connect.Size = new System.Drawing.Size(100, 25);
            this.button_Connect.TabIndex = 6;
            this.button_Connect.Text = "Connect";
            this.button_Connect.UseVisualStyleBackColor = true;
            this.button_Connect.Click += new System.EventHandler(this.button_Connect_Click);
            // 
            // CameraBox
            // 
            this.CameraBox.Location = new System.Drawing.Point(10, 80);
            this.CameraBox.Name = "CameraBox";
            this.CameraBox.Size = new System.Drawing.Size(285, 210);
            this.CameraBox.TabIndex = 3;
            this.CameraBox.TabStop = false;
            this.CameraBox.Text = "Live camera ";
            // 
            // groupBox2
            // 
            this.groupBox2.Controls.Add(this.TextBox_SaveTo);
            this.groupBox2.Controls.Add(this.Btn_Snapshot);
            this.groupBox2.Controls.Add(this.button_SaveTo1);
            this.groupBox2.Location = new System.Drawing.Point(10, 300);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(285, 100);
            this.groupBox2.TabIndex = 37;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "Snapshot";
            // 
            // TextBox_SaveTo
            // 
            this.TextBox_SaveTo.Location = new System.Drawing.Point(119, 63);
            this.TextBox_SaveTo.Name = "TextBox_SaveTo";
            this.TextBox_SaveTo.Size = new System.Drawing.Size(160, 20);
            this.TextBox_SaveTo.TabIndex = 35;
            this.TextBox_SaveTo.Text = "C:\\Users\\user\\Documents\\Visual Studio 2012\\Projects\\03_Onvif_Network_Video_Record" +
                "er\\03_Onvif_Network_Video_Recorder\\bin\\Debug";
            // 
            // Btn_Snapshot
            // 
            this.Btn_Snapshot.Location = new System.Drawing.Point(10, 20);
            this.Btn_Snapshot.Name = "Btn_Snapshot";
            this.Btn_Snapshot.Size = new System.Drawing.Size(100, 25);
            this.Btn_Snapshot.TabIndex = 36;
            this.Btn_Snapshot.Text = "Take a snapshot";
            this.Btn_Snapshot.UseVisualStyleBackColor = true;
            this.Btn_Snapshot.Click += new System.EventHandler(this.Btn_Snapshot_Click);
            // 
            // button_SaveTo1
            // 
            this.button_SaveTo1.Location = new System.Drawing.Point(10, 60);
            this.button_SaveTo1.Name = "button_SaveTo1";
            this.button_SaveTo1.Size = new System.Drawing.Size(100, 25);
            this.button_SaveTo1.TabIndex = 34;
            this.button_SaveTo1.Text = "Save to:";
            this.button_SaveTo1.UseVisualStyleBackColor = true;
            this.button_SaveTo1.Click += new System.EventHandler(this.button_SaveTo_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(309, 414);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.CameraBox);
            this.Controls.Add(this.groupBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Network Video Recorder Snapshot";
            this.groupBox1.ResumeLayout(false);
            this.groupBox2.ResumeLayout(false);
            this.groupBox2.PerformLayout();
            this.ResumeLayout(false);
        }

        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.Button button_Connect;
        private System.Windows.Forms.GroupBox CameraBox;
        private System.Windows.Forms.TextBox TextBox_SaveTo;
        private System.Windows.Forms.Button button_SaveTo1;
        private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
        private System.Windows.Forms.Button Btn_Snapshot;
        private System.Windows.Forms.GroupBox groupBox2;
    }
}

The following figure shows my GUI with my camera image – if you do not change anything in the code above, you should see such a GUI as well. To view the camera image first you need to connect to the camera by clicking on the ’Connect’ button. The camera image will be displayed in the ’Live camera’ section.

The GUI of the IP camera snapshot taker application written in C# - Source: Self made

For taking a snapshot, first of all, click on the ’Save to’ button and define a destination folder where you want to save the image file to. After this, you need to click on the ’Take a snapshot’ button, and the image will be saved automatically into the specified folder.

Due to this C# application, it's now possible for me to capture the most important moments around my table and my PC when I'm not there. Just for fun, take a look at the following figure. I went out of the room and I launched this snapshot taker application on my laptop. I had just left the room, when I noticed that my roommate, Fred, is just tasting my snack. I thought to play a trick with him, and I took a snapshot quickly and I sent it for him through Skype.

As you can see below, I’ve specified that my snapshot will be saved into the ’Snapshots’ folder in the Desktop. After opening this folder, you can also see that the captured still camera image can be found there as a .jpg image file. (And it can be also seen that the file name contains the date and time parameters.)

How to take a snapshot using your C# application - Source: Self made

Finally, I sent the snapshot for my friend via Skype (following figure). He was really surprised. (Do not worry Fred, it was just a joke. My snack is your snack!)

A camera snapshot can be a good evidence - Source: Self made

Conclusion

After making some tests on my previous IP camera project (How to Create a Video Recording Application - NVR/DVR software - for an ONVIF IP Camera using C#.NET), it’s occurred to me that the archiving of events can be carried out not only with video recording, but snapshots would be also useful in a security system. That’s why I came up with a new guide that explains how to take ONVIF IP camera snapshot as a JPG image file using C#.NET. This software allows you to capture the camera image in real time and save it as an image file. It can be useful for security purposes, for preserving and sharing important moments or just for fun. To use my source code, the following prerequisites needed: an ONVIF-compliant camera SDK (like Ozeki Camera SDK) and an IDE for C# programming (like Microsoft Visual Studio).

References

In this section I listed all the webpages that I used as resources to write this article. Below you can also find the direct  download links for the necessary software:

1. http://www.codeproject.com/Articles/825074/How-to-broadcast-live-IP-camera-stream-as-Flash-vi

2. http://www.codeproject.com/Tips/826531/How-to-Create-a-Video-Recording-Application-NVR-DV

3. http://www.onvif.org/specs/core/ONVIF-Core-Spec-v210.pdf

4. http://www.camera-sdk.com/p_13-download-onvif.html

5. http://www.microsoft.com/en-US/download/details.aspx?id=17851

6. http://www.microsoft.com/en-us/download/details.aspx?id=43721

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here