public GetImage ( int timeout, bool makeCopy ) : |
||
timeout | int | Maximum time to wait in milliseconds till image becomes available. |
makeCopy | bool | Make a copy of the camera's image or not. |
return |
public Bitmap GetImage( int timeout, bool makeCopy )
{
lock ( sync )
{
CheckConnection( );
int errorCode;
XimeaImage ximeaImage = new XimeaImage( );
unsafe
{
ximeaImage.StructSize = sizeof( XimeaImage );
}
// get image from XIMEA camera
try
{
errorCode = XimeaAPI.xiGetImage( deviceHandle, timeout, ref ximeaImage );
}
catch ( AccessViolationException )
{
errorCode = 9;
}
// handle error if any
HandleError( errorCode );
// create managed bitmap for the unmanaged image provided by camera
PixelFormat pixelFormat = PixelFormat.Undefined;
int stride = 0;
switch ( ximeaImage.PixelFormat )
{
case ImageFormat.Grayscale8:
pixelFormat = PixelFormat.Format8bppIndexed;
stride = ximeaImage.Width;
break;
case ImageFormat.RGB24:
pixelFormat = PixelFormat.Format24bppRgb;
stride = ximeaImage.Width * 3;
break;
case ImageFormat.RGB32:
pixelFormat = PixelFormat.Format32bppRgb;
stride = ximeaImage.Width * 4;
break;
default:
throw new VideoException( "Unsupported pixel format." );
}
Bitmap bitmap = null;
if ( !makeCopy )
{
bitmap = new Bitmap( ximeaImage.Width, ximeaImage.Height, stride, pixelFormat, ximeaImage.BitmapData );
}
else
{
bitmap = new Bitmap( ximeaImage.Width, ximeaImage.Height, pixelFormat );
// lock destination bitmap data
BitmapData bitmapData = bitmap.LockBits(
new Rectangle( 0, 0, ximeaImage.Width, ximeaImage.Height ),
ImageLockMode.ReadWrite, pixelFormat );
int dstStride = bitmapData.Stride;
int lineSize = Math.Min( stride, dstStride );
unsafe
{
byte* dst = (byte*) bitmapData.Scan0.ToPointer( );
byte* src = (byte*) ximeaImage.BitmapData.ToPointer( );
if ( stride != dstStride )
{
// copy image
for ( int y = 0; y < ximeaImage.Height; y++ )
{
AForge.SystemTools.CopyUnmanagedMemory( dst, src, lineSize );
dst += dstStride;
src += stride;
}
}
else
{
AForge.SystemTools.CopyUnmanagedMemory( dst, src, stride * ximeaImage.Height );
}
}
// unlock destination images
bitmap.UnlockBits( bitmapData );
}
// set palette for grayscale image
if ( ximeaImage.PixelFormat == ImageFormat.Grayscale8 )
{
ColorPalette palette = bitmap.Palette;
for ( int i = 0; i < 256; i++ )
{
palette.Entries[i] = Color.FromArgb( i, i, i );
}
bitmap.Palette = palette;
}
return bitmap;
}
}
// Worker thread private void WorkerThread() { var reasonToStop = ReasonToFinishPlaying.StoppedByUser; try { camera.StartAcquisition(); // while there is no request for stop while (!stopEvent.WaitOne(0, false)) { // start time var start = DateTime.Now; // get next frame var bitmap = camera.GetImage(15000, false); framesReceived++; bytesReceived += bitmap.Width * bitmap.Height * (Bitmap.GetPixelFormatSize(bitmap.PixelFormat) >> 3); if (NewFrame != null) { NewFrame(this, new NewFrameEventArgs(bitmap)); } // free image bitmap.Dispose(); // wait for a while ? if (frameInterval > 0) { // get frame duration var span = DateTime.Now.Subtract(start); // miliseconds to sleep var msec = frameInterval - (int)span.TotalMilliseconds; if ((msec > 0) && (stopEvent.WaitOne(msec, false))) { break; } } } } catch (Exception exception) { reasonToStop = ReasonToFinishPlaying.VideoSourceError; // provide information to clients if (VideoSourceError != null) { VideoSourceError(this, new VideoSourceErrorEventArgs(exception.Message)); } } finally { try { camera.StopAcquisition(); } catch { } } if (PlayingFinished != null) { PlayingFinished(this, reasonToStop); } }