Impact Acquire SDK .NET
ContinuousSaveImage.cs

The ContinuousSaveImage program is a Windows® Forms GUI program which demonstrates how to save images continuously to a hard drive during a live acquisition.

Since
2.44.0
Program location
The source files can be found under:
%INSTALLDIR%\apps\CSharp\ContinuousSaveImage\
Note
If you have installed the package without example applications, these files won't be available. On Windows® the sample application can be installed or removed from the target system at any time by simply restarting the installation package.
ContinuousSaveImage example:
  1. The GUI program starts like this:
  2. Specify a path where images will be saved and choose a camera from the device list. Change the value of Request count, Number of images to save and Image format if required.
  3. Click Use to open the device. When the device is open, you will be able to start image acquisition:
  4. Click Acquire to start the live acquisition.
  5. Once the saving process has completed, statistics regarding the process (e.g. the number of actually saved images, error frames and lost frames) will be displayed in the info box:
  6. All images are now saved under the specified path with name serial-number_frame-ID (e.g. FF000700_1.bmp).
How it works
The two main functions of this program are
  • InitDevice() which initialize the device list.
  • LiveThread() which continuously acquires and saves images from the chosen device, then displays statistics in the info box.
Source code
using mv.impact.acquire.examples.helper;
using System;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace ContinuousSaveImage
{
public partial class ContinuousSaveImage : Form
{
string filePath;
Device device;
Thread thread;
int imagesToSaveCount = 10;
int requestCount = 10;
string[] arrayImageFormat = { "bmp", "jpg", "png", "tif" };
string imageFormat;
bool terminated;
public ContinuousSaveImage()
{
InitializeComponent();
}
private void Frm_Main_Load(object sender, EventArgs e)
{
// Initialize GUI parameters and device list.
comboBoxImgFormat.Items.AddRange(arrayImageFormat);
comboBoxImgFormat.SelectedItem = arrayImageFormat[0];
btnAcquire.Enabled = false;
btnAcquire.BackColor = Color.DarkGray;
btnUse.BackColor = Color.Gainsboro;
textBoxRequestCnt.Text = requestCount.ToString();
textBoxNrImg.Text = imagesToSaveCount.ToString();
InitDevice();
}
private bool TerminateCurrentCaptureThread()
{
if ((thread != null) && (thread.IsAlive))
{
terminated = true;
thread.Join();
return true;
}
return false;
}
private void ContinuousSaveImage_FormClosing(object sender, FormClosingEventArgs e)
{
TerminateCurrentCaptureThread();
}
private void btnBrowse_Click(object sender, EventArgs e)
{
// Choose a path for saving images via the folder browser dialog.
FolderBrowserDialog fbd = new FolderBrowserDialog();
if ((fbd.ShowDialog() == DialogResult.OK) && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
filePath = fbd.SelectedPath;
textBoxPath.Text = filePath;
}
}
private void comboBoxCamera_SelectedIndexChanged(object sender, EventArgs e)
{
// If the previous device is still open, terminate the capture thread if needed, close the previous device and change the button color to gray.
if (device.isOpen)
{
TerminateCurrentCaptureThread();
device.close();
btnUse.BackColor = Color.Gainsboro;
btnAcquire.Enabled = false;
btnAcquire.BackColor = Color.DarkGray;
textBoxFPS.Clear();
textBoxStatistics.Clear();
progressBarSaving.Value = 0;
}
}
private void btnUse_Click(object sender, EventArgs e)
{
// Warning when clicking the 'Use'-button without any camera chosen.
if (comboBoxCamera.SelectedIndex == -1)
{
MessageBox.Show("Please select a camera!");
return;
}
// If the 'Use'-button is gray, open the device and change the button color to blue.
if (btnUse.BackColor == Color.Gainsboro)
{
try
{
device = DeviceManager.getDevice(comboBoxCamera.SelectedIndex);
device.open();
}
{
MessageBox.Show("An error occurred while opening the device: " + ex.errorCodeAsString);
return;
}
btnUse.BackColor = Color.PaleTurquoise;
btnAcquire.Enabled = true;
btnAcquire.BackColor = Color.LimeGreen;
}
// If the 'Use'-button is blue, terminate the capture thread if needed, close the current device and change the button color to gray.
else
{
TerminateCurrentCaptureThread();
device.close();
btnUse.BackColor = Color.Gainsboro;
btnAcquire.Enabled = false;
btnAcquire.BackColor = Color.DarkGray;
textBoxFPS.Clear();
textBoxStatistics.Clear();
progressBarSaving.Value = 0;
}
}
private void btnAcquire_Click(object sender, EventArgs e)
{
// Warning when no saving path is given.
if (string.IsNullOrEmpty(filePath))
{
MessageBox.Show("Please choose chose a valid path for saving image to!");
return;
}
// Terminate the capture thread if the 'Acquire'-button is clicked during acquisition.
if (TerminateCurrentCaptureThread())
{
btnAcquire.BackColor = Color.DarkGray;
return;
}
// Set the 'Acquire'-button to green to indicate that the acquisition is now active.
btnAcquire.BackColor = Color.LimeGreen;
// Read the given request count.
int requestCount = 0;
if (!Int32.TryParse(textBoxRequestCnt.Text, out requestCount) || (requestCount < 2))
{
MessageBox.Show("Invalid request count. Please re-enter the request count (an integer ranged from 2 to 32768)!");
return;
}
// Read the given number of images to save.
int imageCount = 0;
if (!Int32.TryParse(textBoxNrImg.Text, out imageCount) || (imageCount < 1))
{
MessageBox.Show("Invalid number of images to be saved. At least one image has to be captured. Please re-enter the value!");
return;
}
// Initialize the parameters for the GUI output.
progressBarSaving.Minimum = 0;
progressBarSaving.Maximum = imageCount;
imageFormat = comboBoxImgFormat.SelectedItem.ToString();
textBoxFPS.Clear();
textBoxStatistics.Clear();
terminated = false;
// Start capture thread.
thread = new Thread(LiveThread);
thread.Start();
}
private void InitDevice()
{
// This will add folders containing unmanaged libraries to the PATH variable.
// Close the program if no device is found.
{
MessageBox.Show("No camera found!");
Environment.Exit(1);
}
// Create the device list.
for (int deviceIndex = 0; deviceIndex < DeviceManager.deviceCount; deviceIndex++)
{
device = DeviceManager.getDevice(deviceIndex);
comboBoxCamera.Items.Add(device.product.readS() + " " + device.serial.readS());
}
}
private void LiveThread()
{
// Create instances to several camera setting modules.
Statistics statistics = new Statistics(device);
statistics.reset();
SystemSettings ss = new SystemSettings(device);
// Inform the framework about the desired request count.
ss.requestCount.write(requestCount);
// Initialize parameters.
Request request = null;
Request previousRequest = null;
int requestNr = Device.INVALID_ID;
int savedImageCnt = 0;
int imageCnt = 0;
// create the 'FunctionInterface' AFTER modifying the request count in order to
// have a consistent request cache at once (see FunctionInterface.updateRequests for details)!
// Queue up all the request objects.
TDMR_ERROR result = TDMR_ERROR.DMR_NO_ERROR;
while ((result = (TDMR_ERROR)fi.imageRequestSingle()) == TDMR_ERROR.DMR_NO_ERROR) { };
if (result != TDMR_ERROR.DEV_NO_FREE_REQUEST_AVAILABLE)
{
MessageBox.Show("'FunctionInterface.imageRequestSingle' returned with an unexpected result: " + ImpactAcquireException.getErrorCodeAsString(result));
return;
}
// Start the acquisition loop.
DeviceAccess.manuallyStartAcquisitionIfNeeded(device, fi);
while ((imageCnt < imagesToSaveCount) && !terminated)
{
requestNr = fi.imageRequestWaitFor(500);
request = fi.isRequestNrValid(requestNr) ? fi.getRequest(requestNr) : null;
if (request != null)
{
// Read out the current frame ID in the FPS text box.
string frameID = (device.interfaceLayout.read() == TDeviceInterfaceLayout.dilGenICam) ? request.infoFrameID.readS() : request.infoFrameNr.readS();
// Save the image if the current request is OK. Report frame error otherwise.
if (request.isOK)
{
// Output the FPS.
textBoxFPS.BeginInvoke((Action)delegate
{
textBoxFPS.Text = statistics.framesPerSecond.readS();
});
// Output the saving progress in the progress bar.
progressBarSaving.BeginInvoke((Action)delegate
{
progressBarSaving.Value = savedImageCnt;
});
// Save the current image with the given format.
request.save(Path.Combine(filePath, device.serial.readS() + "_" + frameID + "." + imageFormat));
savedImageCnt++;
}
else
{
textBoxStatistics.BeginInvoke((Action)delegate
{
textBoxStatistics.Text += "Frame " + frameID + " has error: " + request.requestResult.readS() + Environment.NewLine;
});
}
// Update the image count.
imageCnt = savedImageCnt + statistics.errorCount.read() + statistics.lostImagesCount.read();
// Unlock the previous request.
if (previousRequest != null)
{
previousRequest.unlock();
}
previousRequest = request;
// Push one empty request object to the request queue.
}
}
// Stop the acquisition.
DeviceAccess.manuallyStopAcquisitionIfNeeded(device, fi);
// Unlock the current request.
if (request != null)
{
request.unlock();
}
// Clear all queues.
// Change the 'Acquire'-button color to gray
btnAcquire.BackColor = Color.DarkGray;
// Display the error frame count and the lost frame count in the statistics box.
if (!terminated)
{
textBoxStatistics.BeginInvoke((Action)delegate
{
textBoxStatistics.Text += Environment.NewLine + savedImageCnt.ToString() +
"/" + imagesToSaveCount.ToString() + " images have been saved successfully." + Environment.NewLine;
textBoxStatistics.Text += "Error Frame Count: " + statistics.errorCount.readS() + Environment.NewLine;
textBoxStatistics.Text += "Lost Frame Count: " + statistics.lostImagesCount.readS();
});
}
}
}
}
Grants access to devices that can be operated by this software interface.
Definition DeviceManager.cs:157
static Device getDevice(int index)
Returns a pointer to a mv.impact.acquire.Device object.
Definition DeviceManager.cs:438
static int deviceCount
Returns the number of devices currently present in the system.
Definition DeviceManager.cs:1064
This class and its functions represent an actual device detected by this interface in the current sys...
Definition Device.cs:91
const int INVALID_ID
A symbolic constant to define an invalid handle.
Definition Device.cs:177
readonly EnumPropertyI< TDeviceInterfaceLayout > interfaceLayout
An enumerated integer property which can be used to define which interface layout shall be used when ...
Definition Device.cs:603
void close()
Closes an opened device.
Definition Device.cs:236
bool isOpen
Returns the current initialisation status in this process.
Definition Device.cs:429
void open()
Opens a device.
Definition Device.cs:208
readonly PropertyS product
A string property (read-only) containing the product name of this device.
Definition Device.cs:501
readonly PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition Device.cs:515
EnumPropertyI< T > write(T value)
Writes one value to the property.
Definition EnumPropertyI.cs:449
T read()
Reads a value from a property.
Definition EnumPropertyI.cs:342
The function interface to devices supported by this interface.
Definition FunctionInterface.cs:21
int imageRequestSingle()
Sends an image request to the mv.impact.acquire.Device driver.
Definition FunctionInterface.cs:656
Request getRequest(int nr)
Returns a const pointer to the desired mv.impact.acquire.Request.
Definition FunctionInterface.cs:452
int imageRequestWaitFor(int timeout_ms)
Waits for a request object to become ready.
Definition FunctionInterface.cs:1021
int imageRequestReset(int requestCtrlNr)
Deletes all requests currently queued for the specified mv.impact.acquire.ImageRequestControl.
Definition FunctionInterface.cs:575
bool isRequestNrValid(int nr)
Check if nr specifies a valid mv.impact.acquire.Request.
Definition FunctionInterface.cs:1098
An base class for exceptions generated by Impact Acquire.
Definition Exceptions.cs:9
static String getErrorCodeAsString(int errorCode)
Returns a string representation of a error.
Definition Exceptions.cs:48
String errorCodeAsString
Returns a string representation of the error associated with the exception.
Definition Exceptions.cs:118
A small helper class to administer various library search path related variables and paths.
Definition LibraryPath.cs:14
static void init()
Calling this method will add the folders containing unmanaged libraries to the systems library search...
Definition LibraryPath.cs:251
String readS()
Reads data from this property as a string.
Definition Property.cs:303
Contains information about a captured buffer.
Definition Request.cs:77
readonly PropertyI64 infoFrameID
A 64 bit integer property (read-only) containing a frame identifier.
Definition Request.cs:1280
int save(String fileName)
Stores the image described by this request into a file.
Definition Request.cs:563
readonly EnumPropertyI< TRequestResult > requestResult
An enumerated integer property (read-only) defining the result of this request.
Definition Request.cs:1211
bool isOK
Convenience function to check if a request has been processed successfully.
Definition Request.cs:1173
readonly PropertyI64 infoFrameNr
A 64 bit integer property (read-only, zero-based) containing the number of image requests processed s...
Definition Request.cs:1287
int unlock()
Unlocks the request for the driver again.
Definition Request.cs:619
Contains statistical information.
Definition Statistics.cs:10
int reset()
Resets all statistical properties.
Definition Statistics.cs:57
readonly PropertyI lostImagesCount
An integer property (read-only) containing the number of images that have been lost from a continuous...
Definition Statistics.cs:133
readonly PropertyI errorCount
An integer property (read-only) containing the overall count of image requests which returned with an...
Definition Statistics.cs:82
readonly PropertyF framesPerSecond
A float property (read-only) containing the current number of frames captured per second.
Definition Statistics.cs:88
A class for accessing general settings that control the overall behaviour of a device driver.
Definition SystemSettings.cs:6
readonly PropertyI requestCount
An integer property defining the number of requests allocated by the driver.
Definition SystemSettings.cs:60
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.cs:2374
TDeviceInterfaceLayout
Defines valid interface layouts for the device.
Definition mvDriverBaseEnums.cs:1921
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition Enumerations.cs:2
Definition Enumerations.cs:2
Definition Enumerations.cs:2