简体   繁体   中英

EDSDK, C#: Trying to get a list of files on the camera

I'm writing an app in C# that uses EDSDK to interface a digital camera with a PC. The user snaps a picture; that triggers an event in the software; and then the software copies the image new image to the PC. That's working great.

Now, I'd like for the software to be able to gracefully handle scenarios where no PC is available or the camera somehow loses connection with the PC. So, whenever a user starts a new session with the software, it first checks to see if there are any images on the camera and, if so, copies them locally. In order to do that, I need a way to get pointers to each individual directory item. So far, I haven't been able to find anything in the documentation or online on how to do this.

Is there any way for EDSDK to get a list of existing files from the camera?

I wrote a function to do this, purely to teach my self the SDK. As such the code isn't used in anything that's in production, thus I give you the relevant function:

       /// <summary>
    /// Gets a list of files on the CF Card. If dest is given, downloads them
    /// </summary>
    /// <param name="dest">string.empty if you just want a list of file names, otherwise the folder in which you want the files</param>
    /// <returns>a list of file names</returns>
    public  List<string> GetPicturesOnCard(string dest)
    {
        IntPtr volumeRef = IntPtr.Zero;
        IntPtr dirRef = IntPtr.Zero;
        IntPtr subDirRef = IntPtr.Zero;
        List<string> result = new List<string>();
        try
        {
            openSession();
            int nFiles;
            if (EDSDK.EdsGetChildAtIndex(camera, 0, out volumeRef) != EDSDK.EDS_ERR_OK)
                throw new CannonException("Couldn't access Memory Card");
            //first child is DCIM
            if (EDSDK.EdsGetChildAtIndex(volumeRef, 0, out dirRef) != EDSDK.EDS_ERR_OK)
                throw new CannonException("Memory Card formatting Error");
           //first child of DCIM has the actual photos
            if(EDSDK.EdsGetChildAtIndex(dirRef, 0, out subDirRef)!= EDSDK.EDS_ERR_OK)
                throw new CannonException("Memory Card formatting Error");
            EDSDK.EdsGetChildCount(subDirRef, out nFiles);  
            for (int i = 0; i < nFiles; i++)
            {      

                IntPtr fileRef = IntPtr.Zero;
                EDSDK.EdsDirectoryItemInfo fileInfo;
                try
                {
                    EDSDK.EdsGetChildAtIndex(subDirRef, i, out fileRef);
                    EDSDK.EdsGetDirectoryItemInfo(fileRef, out fileInfo);
                    if (dest != string.Empty)
                    {
                        IntPtr fStream = IntPtr.Zero;//it's a cannon sdk file stream, not a managed stream
                        uint fSize = fileInfo.Size;
                        try
                        {
                            EDSDK.EdsCreateMemoryStream(fSize, out fStream);
                            if (EDSDK.EdsDownload(fileRef, fSize, fStream) != EDSDK.EDS_ERR_OK)
                                throw new CannonException("Image Download failed");
                            if (EDSDK.EdsDownloadComplete(fileRef) != EDSDK.EDS_ERR_OK)
                                throw new CannonException("Image Download failed to complete");
                            byte[] buffer = new byte[fSize];
                            IntPtr imgLocation;
                            if (EDSDK.EdsGetPointer(fStream, out imgLocation) == EDSDK.EDS_ERR_OK)
                            {
                                Marshal.Copy(imgLocation, buffer, 0, (int)fSize - 1);
                                File.WriteAllBytes(dest + fileInfo.szFileName, buffer);
                            }
                            else
                                throw new CannonException("Interal Error #1");//because the expection text coud land up in a message box some where
                        }
                        finally
                        {
                            EDSDK.EdsRelease(fStream);
                        }
                    }
                }
                finally
                {
                    EDSDK.EdsRelease(fileRef);
                }
                result.Add(fileInfo.szFileName);
            }

        }
        finally
        {
            EDSDK.EdsRelease(subDirRef);
            EDSDK.EdsRelease(dirRef);
            EDSDK.EdsRelease(volumeRef);
            closeSession();
        }

        return result;
    }

Really what you do is: Initialise the SDK, then the camera, then open a session. With that done you then get a reference to the card, then the folder (the folder you want is the first child of the first child), then iterate through all the children there of - they're the files.

The SDK documentation is no fun to read, but will tell you the bits I've missed out (How to initialise the camera and so on, which I'm assuming you know how to do from the rest of the project).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM