take picture and directly save image to pc using edsdk 2.8

◇◆丶佛笑我妖孽 提交于 2019-12-06 13:13:51

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);
            }
        }
Jim

I am doing the same in that I have no memory card in the camera and want to transfer the image to the host computer after the take picture command is sent. Here is what worked for me to get the ObjectEventHandler callback called when no memory card is installed in the Canon EOS50D.

EdsUInt32 setsaveto = kEdsSaveTo_Both;
err = EdsSetPropertyData(camera, kEdsPropID_SaveTo, 0, sizeof(setsaveto), &setsaveto);

Voila, the callback gets called and I can then proceed to do the getCapturedItem() function as Wayne has posted in the earlier post.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!