Esempio n. 1
0
        /// <summary>
        /// Get image from the opened XIMEA camera.
        /// </summary>
        /// 
        /// <param name="timeout">Maximum time to wait in milliseconds till image becomes available.</param>
        /// <param name="makeCopy">Make a copy of the camera's image or not.</param>
        /// 
        /// <returns>Returns image retrieved from the camera.</returns>
        /// 
        /// <remarks><para>If the <paramref name="makeCopy"/> is set to <see langword="true"/>, then the method
        /// creates a managed copy of the camera's image, so the managed image stays valid even when the camera
        /// is closed. However, setting this parameter to <see langword="false"/> creates a managed image which is
        /// just a wrapper around camera's unmanaged image. So if camera is closed and its resources are freed, the
        /// managed image becomes no longer valid and accessing it will generate an exception.</para></remarks>
        /// 
        /// <exception cref="VideoException">An error occurred while communicating with a camera. See error
        /// message for additional information.</exception>
        /// <exception cref="NotConnectedException">No camera was opened, so can not access its methods.</exception>
        /// <exception cref="TimeoutException">Time out value reached - no image is available within specified time value.</exception>
        ///
        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++ )
                            {
                                Accord.SystemTools.CopyUnmanagedMemory( dst, src, lineSize );
                                dst += dstStride;
                                src += stride;
                            }
                        }
                        else
                        {
                            Accord.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;
            }
        }
 public static extern int xiGetImage(IntPtr deviceHandle, int timeout, [In, MarshalAs(UnmanagedType.Struct)] ref XimeaImage image);