/// <summary> /// Get a list of all pointer of the cameras connected to the host /// </summary> /// <returns>A list of connected cameras as pointer</returns> /// <exception cref="ObjectDisposedException">This instance has been disposed already</exception> /// <exception cref="SDKException">An SDK call failed</exception> protected IEnumerable <IntPtr> GetCameraPointerList() { if (IsDisposed) { throw new ObjectDisposedException(nameof(CanonAPI)); } IntPtr camlist; //Get camera list ErrorHandler.CheckError(this, CanonSDK.EdsGetCameraList(out camlist)); //Get number of connected cameras int camCount; ErrorHandler.CheckError(this, CanonSDK.EdsGetChildCount(camlist, out camCount)); List <IntPtr> ptrList = new List <IntPtr>(); for (int i = 0; i < camCount; i++) { //Get camera pointer IntPtr cptr; ErrorHandler.CheckError(this, CanonSDK.EdsGetChildAtIndex(camlist, i, out cptr)); ptrList.Add(cptr); } //Release the list ErrorHandler.CheckError(this, CanonSDK.EdsRelease(camlist)); return(ptrList); }
/// <summary> /// Gets a <see cref="Bitmap"/> from an EDSDK pointer to an image (Jpg or Raw) /// </summary> /// <param name="imgStream">Stream pointer to the image</param> /// <param name="imageSource">The result image type</param> /// <returns>A <see cref="Bitmap"/> image from the given stream pointer</returns> protected Bitmap GetImage(IntPtr imgStream, ImageSource imageSource) { IntPtr imgRef = IntPtr.Zero; IntPtr streamPointer = IntPtr.Zero; ImageInfo imageInfo; try { //create reference and get image info ErrorHandler.CheckError(this, CanonSDK.EdsCreateImageRef(imgStream, out imgRef)); ErrorHandler.CheckError(this, CanonSDK.EdsGetImageInfo(imgRef, imageSource, out imageInfo)); Size outputSize = new Size(); outputSize.Width = imageInfo.EffectiveRect.Width; outputSize.Height = imageInfo.EffectiveRect.Height; //calculate amount of data int datalength = outputSize.Height * outputSize.Width * 3; //create buffer that stores the image byte[] buffer = new byte[datalength]; //create a stream to the buffer using (var stream = new SDKStream(buffer)) { //load image into the buffer ErrorHandler.CheckError(this, CanonSDK.EdsGetImage(imgRef, imageSource, TargetImageType.RGB, imageInfo.EffectiveRect, outputSize, stream.Reference)); //make BGR from RGB (System.Drawing (i.e. GDI+) uses BGR) unsafe { byte tmp; fixed(byte *pix = buffer) { for (long i = 0; i < datalength; i += 3) { tmp = pix[i]; //Save B value pix[i] = pix[i + 2]; //Set B value with R value pix[i + 2] = tmp; //Set R value with B value } } } //Get pointer to stream data ErrorHandler.CheckError(this, CanonSDK.EdsGetPointer(stream.Reference, out streamPointer)); //Create bitmap with the data in the buffer return(new Bitmap(outputSize.Width, outputSize.Height, datalength, PixelFormat.Format24bppRgb, streamPointer)); } } finally { //Release all data if (imgStream != IntPtr.Zero) { ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgStream)); } if (imgRef != IntPtr.Zero) { ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgRef)); } } }
/// <summary> /// Initializes the SDK /// </summary> /// <param name="useCallingThread">If true, the calling thread will be used as SDK main thread; /// if false, a separate thread will be created</param> public CanonAPI(bool useCallingThread) { try { //Ensure that only one caller at a time can increase the counter lock (InitLock) { //If no instance exists yet, initialize everything if (RefCount == 0) { if (useCallingThread) { if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) { throw new ThreadStateException("Calling thread must be in STA"); } ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK()); } else { //Trying to trigger DllNotFoundException so it's not thrown //in the event loop on a different thread: CanonSDK.EdsRelease(IntPtr.Zero); //Start the main thread where SDK will run on MainThread = new ApiThread(); MainThread.Start(); //Initialize the SDK on the main thread MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK())); } CanonSDK.InitializeVersion(); //Subscribe to the CameraAdded event CameraAddedEvent = new SDKCameraAddedHandler(CanonAPI_CameraAddedEvent); ErrorHandler.CheckError(this, CanonSDK.EdsSetCameraAddedHandler(CameraAddedEvent, IntPtr.Zero)); _IsSDKInitialized = true; } RefCount++; } } catch (Exception e) { IsDisposed = true; if (MainThread?.IsRunning == true) { MainThread.Shutdown(); } throw; } }
/// <summary> /// Releases this entry but not the subentries /// </summary> /// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param> protected virtual void Dispose(bool managed) { if (!IsDisposed) { if (managed) { DisposeThumb(); } if (Reference != IntPtr.Zero) { CanonSDK.EdsRelease(Reference); } IsDisposed = true; } }