質問

EDSDK 2.8は初めてです

現時点では、私のプログラムは写真を撮ることができます。ただし、写真を撮ると、その写真は一時的にキヤノンカメラのバッファーに保存されます。ディレクトリをPCに保存する方法を知りたいですか?

誰かがアイデアを持っていますか?または、C#またはvb.netのサンプルコード?

役に立ちましたか?

解決

これが私がやったことです:

まず、オブジェクトが作成されたときにコールバックイベントに登録する必要があります(つまり、写真)。これを作成したRegisterEventsメソッドでこれを行いました。

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

vaila、コールバックが呼び出され、その後、 getCapturedItem() ウェインが以前の投稿に投稿したように機能します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top