using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
namespace mv.impact.acquire.examples
{
public partial class MainForm : Form
{
#region static private members ---------------------------------------------------
private static readonly System.Drawing.Font font_ = new System.Drawing.Font("Arial", 10);
private static readonly System.Drawing.Pen pen_ = new System.Drawing.Pen(Color.Blue, 10);
#endregion
#region private members ----------------------------------------------------------
private readonly Stopwatch imageProcessingTimer_ = new Stopwatch();
private int requestsInitiallyQueued_ = 0;
private int requestsSuccessfullyCaptured_ = 0;
private int requestsSentToDisplay_ = 0;
private double percentageOfImagesSentToTheDisplay_ = 100;
private string currentBandwidthMsg_ = string.Empty;
private string lastErrorMsg_ = string.Empty;
private readonly Object internalLock_ = new Object();
private readonly System.Timers.Timer overlayTextRefreshUpdateTimer_ = null;
private bool threadsTerminated_ = true;
private Thread updateThread_ = null;
private readonly AutoResetEvent newImageAvailableEvent_ = new AutoResetEvent(false);
#endregion
#region private methods ----------------------------------------------------------
private void CleanupPreviousRequest()
{
if (bitmapDataCurrentlyDisplayed_ != null)
{
bitmapDataCurrentlyDisplayed_.
Dispose();
requestCurrentlyDisplayed_.
unlock();
}
}
private Request GetRequestToDisplayNext()
{
Request r = null;
lock (internalLock_)
{
r = requestToDisplayNext_;
requestToDisplayNext_ = null;
}
return r;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
overlayTextRefreshUpdateTimer_.Enabled = false;
threadsTerminated_ = true;
CleanupPreviousRequest();
}
private void MainForm_Load(object sender, EventArgs e)
{
for (int i = 0; i < DeviceManager.deviceCount; i++)
{
comboBoxDeviceSelection.Items.Add("[" + i + "] - " + (DeviceManager.getDevice(i)).serial.readS());
}
}
private unsafe void ModifyBitmapBuffer(Bitmap bmp)
{
int pixWidth = 1;
switch (bmp.PixelFormat)
{
case PixelFormat.Format8bppIndexed:
pixWidth = 1;
break;
case PixelFormat.Format24bppRgb:
pixWidth = 3;
break;
case PixelFormat.Format32bppRgb:
case PixelFormat.Format32bppPArgb:
case PixelFormat.Format32bppArgb:
pixWidth = 4;
break;
default:
Debug.Assert(false, "Unsupported pixel format!", "This code needs to be adjusted to handle '" + bmp.PixelFormat.ToString() + "' data!");
break;
}
BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr scan0 = bmData.Scan0;
int stride = bmData.Stride;
int x0 = bmp.Width / 4;
int y0 = bmp.Height / 4;
int x1 = 3 * bmp.Width / 4;
int y1 = 3 * bmp.Height / 4;
byte val0 = ((byte*)scan0.ToPointer())[2];
switch (bmp.PixelFormat)
{
case PixelFormat.Format8bppIndexed:
for (int y = y0; y < y1; y++)
{
byte* p = (byte*)scan0.ToPointer() + y * stride;
for (int x = x0; x < x1; x++)
{
p[x] = (byte)(val0 + y);
}
}
break;
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
case PixelFormat.Format32bppPArgb:
case PixelFormat.Format32bppArgb:
for (int y = y0; y < y1; y++)
{
byte* p = (byte*)scan0.ToPointer() + y * stride + x0 * pixWidth;
for (int x = x0; x < x1; x++)
{
p[0] = (byte)(val0 + y);
p[1] = (byte)(val0 + y);
p[2] = (byte)(val0 + y);
p += pixWidth;
}
}
break;
}
bmp.UnlockBits(bmData);
}
private void OnOverlayTextRefreshUpdate(object source, ElapsedEventArgs e)
{
lock (internalLock_)
{
UpdatePercentageOfImagesSentToDisplay();
currentBandwidthMsg_ = String.Format("Capture rate: {0:0.00} Hz ({1:0.00} MB/s), display rate: {2:0.00} Hz, using {3} buffers",
fps,
fps * percentageOfImagesSentToTheDisplay_ / 100.0,
requestsInitiallyQueued_);
}
}
private void UnlockRequest(Request request)
{
if (request != null)
{
request.unlock();
}
}
private void UpdateImage(Request request)
{
if (request != null)
{
imageProcessingTimer_.Reset();
imageProcessingTimer_.Start();
if (cbModifyBitmapBuffer.Checked)
{
ModifyBitmapBuffer(data.
bitmap);
}
this.pictureBoxImage.Image = data.
bitmap;
CleanupPreviousRequest();
requestCurrentlyDisplayed_ = request;
bitmapDataCurrentlyDisplayed_ = data;
imageProcessingTimer_.Stop();
}
}
private void UpdatePercentageOfImagesSentToDisplay()
{
lock (internalLock_)
{
double result = (requestsSuccessfullyCaptured_ == 0) ? 100.0 : 100.0 * (double)requestsSentToDisplay_ / (double)requestsSuccessfullyCaptured_;
requestsSentToDisplay_ = 0;
requestsSuccessfullyCaptured_ = 0;
percentageOfImagesSentToTheDisplay_ = 0.9 * percentageOfImagesSentToTheDisplay_ + 0.1 * result;
}
}
#endregion
#region private GUI methods ------------------------------------------------------
private void buttonStartStop_Click(object sender, EventArgs e)
{
buttonStartStop.Text = threadsTerminated_ ? "Stop Live" : "Start Live";
threadsTerminated_ = !threadsTerminated_;
overlayTextRefreshUpdateTimer_.Enabled = !threadsTerminated_;
Thread captureThread = new Thread(delegate ()
{
TDMR_ERROR result = TDMR_ERROR.DMR_NO_ERROR;
requestsInitiallyQueued_ = 0;
while ((result = (TDMR_ERROR)functionInterface_.
imageRequestSingle()) == TDMR_ERROR.DMR_NO_ERROR)
{
++requestsInitiallyQueued_;
};
{
if ((result = (TDMR_ERROR)functionInterface_.
acquisitionStart()) != TDMR_ERROR.DMR_NO_ERROR)
{
lock (internalLock_)
{
lastErrorMsg_ = "'FunctionInterface.acquisitionStart' returned with an unexpected result: " + result + "( " + ImpactAcquireException.getErrorCodeAsString(result) + ")";
}
}
}
requestsSuccessfullyCaptured_ = 0;
requestsSentToDisplay_ = 0;
Request pRequest = null;
int timeout_ms = 500;
int requestNr = Device.INVALID_ID;
while (!threadsTerminated_)
{
lock (internalLock_)
{
if (pRequest != null)
{
if (pRequest.isOK)
{
++requestsSuccessfullyCaptured_;
if (requestToDisplayNext_ == null)
{
requestToDisplayNext_ = pRequest;
pRequest = null;
newImageAvailableEvent_.Set();
++requestsSentToDisplay_;
}
else
{
UnlockRequest(pRequest);
}
lastErrorMsg_ = string.Empty;
}
else
{
UnlockRequest(pRequest);
lastErrorMsg_ = "Error: " + pRequest.requestResult.readS();
}
}
else
{
lastErrorMsg_ = "imageRequestWaitFor failed (" + requestNr + ", " + ImpactAcquireException.getErrorCodeAsString(requestNr) + "), timeout value (" + timeout_ms + ") too small?";
}
}
}
{
if ((result = (TDMR_ERROR)functionInterface_.
acquisitionStop()) != TDMR_ERROR.DMR_NO_ERROR)
{
lock (internalLock_)
{
lastErrorMsg_ = "'FunctionInterface.acquisitionStop' returned with an unexpected result: " + result + "( " + ImpactAcquireException.getErrorCodeAsString(result) + ")";
}
}
}
UnlockRequest(pRequest);
requestNr = Device.INVALID_ID;
{
UnlockRequest(functionInterface_.
getRequest(requestNr));
}
});
updateThread_ = new Thread(delegate ()
{
while (!threadsTerminated_)
{
if (newImageAvailableEvent_.WaitOne(TimeSpan.FromMilliseconds(100)))
{
try
{
Request pRequest = GetRequestToDisplayNext();
Invoke(new MethodInvoker(() => { UpdateImage(pRequest); }));
}
catch (Exception)
{
}
}
}
});
if (!threadsTerminated_)
{
updateThread_.Start();
captureThread.Start();
}
}
private void comboBoxDeviceSelection_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
dev_ = DeviceManager.getDevice(comboBoxDeviceSelection.SelectedIndex);
if (dev_.interfaceLayout.isValid && dev_.interfaceLayout.listOfValidValues.Contains(TDeviceInterfaceLayout.dilGenICam))
{
dev_.interfaceLayout.write(TDeviceInterfaceLayout.dilGenICam);
dev_.acquisitionStartStopBehaviour.write(TAcquisitionStartStopBehaviour.assbUser);
}
statistics_ = new Statistics(dev_);
functionInterface_ = new FunctionInterface(dev_);
}
catch (ImpactAcquireException ex)
{
MessageBox.Show(ex.errorCodeAsString);
Environment.Exit(42);
}
comboBoxDeviceSelection.Enabled = false;
buttonStartStop.Enabled = true;
}
private void pictureBoxImage_Paint(object sender, PaintEventArgs e)
{
if (cbDrawCustomOverlay.Checked)
{
lock (internalLock_)
{
int xOff = this.pictureBoxImage.Width / 4;
int yOff = 50;
Graphics g = e.Graphics;
g.DrawString(String.Format("Bitmap ({0}x{1}@{2}) processing time: {3} ms ({4})",
this.pictureBoxImage.Image.Width,
this.pictureBoxImage.Image.Height,
this.pictureBoxImage.Image.PixelFormat.ToString(),
imageProcessingTimer_.ElapsedMilliseconds,
imageProcessingTimer_.Elapsed),
font_, Brushes.Red, xOff, yOff);
if (currentBandwidthMsg_.Length > 0)
{
yOff += 25;
g.DrawString(currentBandwidthMsg_, font_, Brushes.Red, xOff, yOff);
}
if (lastErrorMsg_.Length > 0)
{
yOff += 25;
g.DrawString(lastErrorMsg_, font_, Brushes.Red, xOff, yOff);
}
int xR = pictureBoxImage.Size.Width / 4;
int yR = pictureBoxImage.Size.Height / 4;
int wR = pictureBoxImage.Size.Width / 2;
int hR = pictureBoxImage.Size.Height / 2;
Rectangle rect = new Rectangle(xR, yR, wR, hR);
g.DrawRectangle(pen_, rect);
int xUpper = xR + wR / 2;
int yLower = yR + hR;
int xLowerRight = xR + wR;
g.DrawLine(pen_, xUpper, yR, xR, yLower);
g.DrawLine(pen_, xUpper, yR, xLowerRight, yLower);
g.DrawLine(pen_, xR, yLower, xLowerRight, yLower);
int centerX = pictureBoxImage.Size.Width / 2;
int centerY = pictureBoxImage.Size.Height / 2;
int radius = Math.Min(centerX, centerY) / 2;
g.DrawEllipse(pen_, centerX - radius, centerY - radius, 2 * radius, 2 * radius);
}
}
}
#endregion
#region public constructors ------------------------------------------------------
public MainForm()
{
this.DoubleBuffered = true;
InitializeComponent();
overlayTextRefreshUpdateTimer_ = new System.Timers.Timer();
overlayTextRefreshUpdateTimer_.Interval = 1000;
overlayTextRefreshUpdateTimer_.Elapsed += new ElapsedEventHandler(OnOverlayTextRefreshUpdate);
}
#endregion
}
}
This class and its functions represent an actual device detected by this interface in the current sys...
Definition Device.cs:91
readonly EnumPropertyI< TAcquisitionStartStopBehaviour > acquisitionStartStopBehaviour
An enumerated integer property defining the start/stop behaviour during acquisition of this driver in...
Definition Device.cs:731
T read()
Reads a value from a property.
Definition EnumPropertyF.cs:323
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
int acquisitionStop()
Manually stops the acquisition engine of this device driver instance.
Definition FunctionInterface.cs:548
int acquisitionStart()
Manually starts the acquisition engine of this device driver instance.
Definition FunctionInterface.cs:521
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
A class containing a reference to a bitmap created from a request.
Definition RequestBitmapData.cs:31
void Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resourc...
Definition RequestBitmapData.cs:80
System.Drawing.Bitmap bitmap
A reference to the System.Drawing.Bitmap contained in this mv.impact.acquire.RequestBitmapData instan...
Definition RequestBitmapData.cs:94
Contains information about a captured buffer.
Definition Request.cs:77
int unlock()
Unlocks the request for the driver again.
Definition Request.cs:619
Contains statistical information.
Definition Statistics.cs:10
readonly PropertyF bandwidthConsumed
A float property (read-only) containing the current bandwidth consumed by this device in KB/s based o...
Definition Statistics.cs:80
readonly PropertyF framesPerSecond
A float property (read-only) containing the current number of frames captured per second.
Definition Statistics.cs:98