Search code examples
c++canon-sdkeos

Canon EOS SDK download taken picture directly to a buffer or stream


It is quite easy to obtain the Image during live view operation using the method

EdsDownloadEvfImage(CameraRef, ImageRef);

This is quite handy to perform further image processing (with OpenCV etc)

In the same way, I would like to obtain the image data on taking a photo. In the documentation, I could only find a way to download image to PC using

EdsError EdsDownload(EdsDirectoryItemRef inDirItemRef, EdsUInt64 inReadSize, EdsStreamRef OutStreamRef)

Is there any convenient way to load the taken image to a stream or buffer directly?


Solution

  • There isn't, but it's also not that difficult to do either. Because there is more than one way to obtain an image, it can't be as easy as downloading a live view image.

    If you want to get the image directly after taking it, do the following:

    • Set the SaveTo property to Host and listen to the ObjectEvent.
    • Once the event fires with the event type of DirItemRequestTransfer you can get the necessary info with EdsGetDirectoryItemInfo
    • Create a memory stream with EdsCreateMemoryStream
    • Call EdsDownload with the EdsDirectoryItemInfo you got earlier and for inReadSize you just use the size field from said struct (if you want to use smaller chunks and progress events, check the docs for more info).
    • After the download is done, make sure to call EdsDownloadComplete and of course release everything

    If you don't intend to download the image you must call EdsDownloadCancel or the camera will retain the image in the buffer which will fill up and block the camera from switching off as well (you'll have to remove the battery to force it off).

    If you want to download an image that is saved on the memory card of the camera, it gets a bit more complicated because you first have to traverse the directory structure to find the image you want. I won't go into the full details and you best read the docs for that but here are the rough steps:

    • Get the number of volumes the camera has with EdsGetChildCount where inRef is the camera
    • Loop through the volumes with EdsGetChildAtIndex (again using the camera for inRef) and EdsGetVolumeInfo
    • Then basically do the same thing over and over but use EdsGetDirectoryItemInfo instead of EdsGetVolumeInfo. For inRef with EdsGetChildCount and EdsGetChildAtIndex you either use the volume reference or the directory item reference if it's a folder (check the isFolder field of the EdsDirectoryItemInfo struct).
    • To download a file you do the same as before, use EdsDownload and EdsCreateMemoryStream