خذ الصورة وحفظ الصورة مباشرة إلى الكمبيوتر باستخدام EDSDK 2.8

StackOverflow https://stackoverflow.com/questions/3762530

  •  04-10-2019
  •  | 
  •  

سؤال

أنا جديد على EDSDK 2.8

في الوقت الحالي ، يمكن للبرنامج التقاط الصور. ومع ذلك ، عند التقاط صورة ، يتم تخزين تلك الصورة مؤقتًا في المخزن المؤقت في كاميرا Canon. أود أن أعرف كيفية حفظه دليل الكمبيوتر؟

هل لدى أي شخص أي أفكار؟ أو عينة رمز في C# أو VB.NET؟

هل كانت مفيدة؟

المحلول

هذا ما فعلته:

أولاً ، يجب عليك التسجيل في حدث رد الاتصال عند إنشاء كائن (أي صورة). فعلت هذا في طريقة التسجيلات التي قمت بإنشائها:

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

ال objectEventHandler هي الطريقة التي سيتم استدعاؤها عند إنشاء صورة.

تحتاج الطريقة إلى الامتثال للواجهة التي تمليها API. إليك مثال على تنفيذ هذه الطريقة:

/// <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;
}

في هذا المثال ، استدير وأفرخ الحدث الخاص بي ، والذي يحتوي على الإشارة إلى كائن الدفق. يتم التعامل مع هذا من قبل الكود التالي:

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

نصائح أخرى

أفعل نفس الشيء من حيث أنه ليس لدي بطاقة ذاكرة في الكاميرا وأريد نقل الصورة إلى الكمبيوتر المضيف بعد إرسال أمر Take Picture. إليكم ما نجح لي للحصول على ObjectEventHandler استدعاء رد الاتصال عندما لا يتم تثبيت بطاقة ذاكرة في Canon EOS50D.

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

Voila ، يتم استدعاء رد الاتصال ويمكنني بعد ذلك المتابعة للقيام getCapturedItem() وظيفة كما نشر واين في المنشور السابق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top