Search code examples
c#.netimageedsdk

take picture and directly save image to pc using edsdk 2.8


I'm new to the EDSDK 2.8

At the moment, my program can take pictures. However, when a picture is taken, that picture is temporarily stored in a buffer in the Canon camera. I would like to know how to save it directory to the PC?

Does anyone have any ideas? Or sample code in c# or vb.net?


Solution

  • Here is what I have done:

    First, you have to register for the callback event when an object is created (ie, a picture). I did this in a registerEvents method that I created:

    //  Register OBJECT events
    edsObjectEventHandler = new EDSDK.EdsObjectEventHandler(objectEventHandler);
    error = EDSDK.EdsSetObjectEventHandler(this.CameraDevice, 
                    EDSDK.ObjectEvent_All, edsObjectEventHandler, IntPtr.Zero);
    if (EDSDK.EDS_ERR_OK != error)
    {
        throw new CameraEventRegistrationException("Unable to
            register object events with the camera!", error);
    }
    

    The objectEventHandler is the method that will be called when a picture is created.

    The method needs to conform to the interface dictated by the API. Here's an example implementation of that method:

    /// <summary>
    /// Registered callback function for recieving object events
    /// </summary>
    /// <param name="inEvent">Indicate the event type supplemented.</param>
    /// <param name="inRef">Returns a reference to objects created by the event.</param>
    /// <param name="inContext">Passes inContext without modification</param>
    /// <returns>Status 0 (OK)</returns>
    private uint objectEventHandler(uint inEvent, IntPtr inRef, IntPtr inContext)
    {
        switch (inEvent)
        {
            case EDSDK.ObjectEvent_DirItemCreated:
                 this.invokeNewItemCreatedEvent(new NewItemCreatedEventArgs(getCapturedItem(inRef)));
                 Console.WriteLine("Directory Item Created");
                 break;
            case EDSDK.ObjectEvent_DirItemRequestTransfer:
                 Console.WriteLine("Directory Item Requested Transfer");
                 break;
             default:
                 Console.WriteLine(String.Format("ObjectEventHandler: event {0}, ref {1}", inEvent.ToString("X"), inRef.ToString()));
                 break;
        }
    
        return 0x0;
    }
    

    In this example I turn around and spawn my own event, which has the reference to the stream object. This is handled by the following code:

            /// <summary>
            /// Gets a photo or video clip from the camera
            /// </summary>
            /// <param name="directoryItem">Reference to the item that the camera captured.</param>
            /// <returns></returns>
            private CapturedItem getCapturedItem(IntPtr directoryItem)
            {
                uint err = EDSDK.EDS_ERR_OK;
                IntPtr stream = IntPtr.Zero;
    
                EDSDK.EdsDirectoryItemInfo dirItemInfo;
    
                err = EDSDK.EdsGetDirectoryItemInfo(directoryItem, out dirItemInfo);
    
                if (err != EDSDK.EDS_ERR_OK)
                {
                    throw new CameraException("Unable to get captured item info!", err);
                }
    
                //  Fill the stream with the resulting image
                if (err == EDSDK.EDS_ERR_OK)
                {
                    err = EDSDK.EdsCreateMemoryStream((uint)dirItemInfo.Size, out stream);
                }
    
                //  Copy the stream to a byte[] and 
                if (err == EDSDK.EDS_ERR_OK)
                {
                    err = EDSDK.EdsDownload(directoryItem, (uint)dirItemInfo.Size, stream);
                }
    
                //  Create the returned item
                CapturedItem item = new CapturedItem();
    
                if (err == EDSDK.EDS_ERR_OK)
                {
                    IntPtr imageRef = IntPtr.Zero;
    
                    err = EDSDK.EdsCreateImageRef(stream, out imageRef);
    
                    if (err == EDSDK.EDS_ERR_OK)
                    {
                        EDSDK.EdsImageInfo info;
                        err = EDSDK.EdsGetImageInfo(imageRef, EDSDK.EdsImageSource.FullView, out info);
    
                        if (err == EDSDK.EDS_ERR_OK)
                        {
                            item.Dimensions = new com.waynehartman.util.graphics.Dimension((int)info.Width, (int)info.Height);
    
                            EDSDK.EdsRelease(imageRef);
                        }
                    }
                }
    
                if (err == EDSDK.EDS_ERR_OK)
                {
                    byte[] buffer = new byte[(int)dirItemInfo.Size];
    
                    GCHandle gcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
    
                    IntPtr address = gcHandle.AddrOfPinnedObject();
    
                    IntPtr streamPtr = IntPtr.Zero;
    
                    err = EDSDK.EdsGetPointer(stream, out streamPtr);
    
                    if (err != EDSDK.EDS_ERR_OK)
                    {
                        throw new CameraDownloadException("Unable to get resultant image.", err);
                    }
    
                    try
                    {
                        Marshal.Copy(streamPtr, buffer, 0, (int)dirItemInfo.Size);
    
                        item.Image = buffer;
                        item.Name = dirItemInfo.szFileName;
                        item.Size = (long)dirItemInfo.Size;
                        item.IsFolder = Convert.ToBoolean(dirItemInfo.isFolder);
    
                        return item;
                    }
                    catch (AccessViolationException ave)
                    {
                        throw new CameraDownloadException("Error copying unmanaged stream to managed byte[].", ave);
                    }
                    finally
                    {
                        gcHandle.Free();
                        EDSDK.EdsRelease(stream);
                        EDSDK.EdsRelease(streamPtr);
                    }
                }
                else
                {
                    throw new CameraDownloadException("Unable to get resultant image.", err);
                }
            }