Domanda

Sono nuovo al EDSDK 2.8

Al momento, il mio programma può scattare foto. Tuttavia, quando si scatta una foto, quella foto viene temporaneamente memorizzato in un buffer nella fotocamera Canon. Vorrei sapere come salvarlo directory al PC?

Qualcuno ha qualche idea? O codice di esempio in C # o vb.net?

È stato utile?

Soluzione

Ecco quello che ho fatto:

In primo luogo, è necessario registrarsi per l'evento di callback quando un oggetto viene creato (ad esempio, una foto). Ho fatto questo in un metodo registerEvents che ho creato:

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

Il objectEventHandler è il metodo che verrà chiamato quando viene creata una foto.

Il metodo deve essere conforme al dettato interfaccia dall'API. Ecco un esempio di implementazione di tale metodo:

/// <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 questo esempio mi giro e deporre le uova il mio proprio evento, che ha il riferimento all'oggetto flusso. Questo è gestito dal seguente codice:

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

Altri suggerimenti

io sto facendo lo stesso in quanto non ho alcuna scheda di memoria nella fotocamera e voglio trasferire l'immagine al computer host dopo il comando prende l'immagine viene inviato. Ecco che cosa ha funzionato per me per ottenere la richiamata ObjectEventHandler chiamato quando alcuna scheda di memoria è installata nel Canone EOS50D.

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

Voila, la richiamata viene chiamato e posso quindi procedere a fare la funzione getCapturedItem() come Wayne ha pubblicato nel post precedente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top