Thursday, May 03, 2012

A short note about using Canon EDSDK


I had been trying to automate an imaging process using a Canon 40D and Canon EDSDK 2.10. Basically, I wanted the camera to take a picture and send the image (directly from the camera buffer) to my computer. The computer would save/process the image afterwards.

I didn't want to have the camera saved the images on the memory card, since I needed to take a lot of images and I only had a 2 GB card.

I followed the samples in the Canon EDSDK API document and the VC sample code. My code was written in C.

At start, I couldn't have the object event handler worked properly. No object event was detected, even property and camera state events could be found. After countless attempts, I finally know why. I wrote what I found here and hope that it will be useful for other people as well.

1. Add a Windows message loop. 
It seems that the EDSDK relies on the Windows message loop to fire and dispatch events. Without it, no object event can be fired (so the object event handlers are never called).



Note that my code is written in Visual C++ Express 2010, and the subsystem in the project setting is Console (not Windows).

2. Set kEdsPropID_SaveTo property to SaveTo_Host. 



Somehow this property on my camera was set to SaveTo_Camera. Therefore, event 520 (kEdsObjectEvent_DirItemRequestTransfer) had never been fired after a picture was taken. Set it to SaveTo_Host and everything is fine.

3. Catch event kEdsObjectEvent_DirItemCreated
It is possible to retrieve the image from the memory card when kEdsPropID_SaveTo property is set to SaveTo_Camera. The workaround is to catch is event 516 (kEdsObjectEvent_DirItemCreated). As this is more like a trick, I do not recommend using it.

Ensure that the memory card is inserted to the camera. Otherwise, no event 516 can be generated.

8 comments :

  1. Thanks your explanation was usefull!.

    I had never discovered the "GetMessage(&msg, NULL, NULL, NULL)"
    withouth you.

    ReplyDelete
  2. But I have still a problem. Sometimes when I change the saveTo property to specify that the image will be saved in the computer, the takePicture function return me a "EDS_ERR_TAKE_PICTURE_CARD_NG" error writing to card.

    ReplyDelete
  3. Ok Solved, after set the saveToHost property you have to reserved the capacity memory using the function:

    EdsCapacity newCapacity = {0x7FFFFFFF, 0x1000, 1};
    err = EdsSetCapacity(camera, newCapacity );

    ReplyDelete
  4. Wow, this post saved my life. I could not figure out why the event would never fire...! Thanks, your solution works perfectly

    ReplyDelete
  5. if i use C# .NET where i have to put
    while (GetMessage(&msg, NULL, NULL, NULL))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    this??
    thanks,,

    ReplyDelete
  6. This was the solution to downloading image. However it will not break from the loop! Does anyone have the solution for this?

    ReplyDelete
  7. Hello Son,

    Thanks for good explanation. I am also started using Canon EDS SDK in Mac app and getting EDS_ERR_TAKE_PICTURE_CARD_NG error but not always. Scenario is if I normally connect/disconnect the camera then next time taking the picture works fine. But if i directly unplug the camera using USB cable and plug it back, it does not work and gives EDS_ERR_TAKE_PICTURE_CARD_NG error and shows "PC Full" error on camera screen. To use it again, have to restart the camera.

    I have checked and verified that EdsCapacity is also properly set when plugged in. Any help will be appreciated. Waiting for your reply.

    Thanks,
    Mahesh.

    ReplyDelete
  8. @Mahesh: not sure if you will read this as this reply seems too late :p

    It's quite a long time ago that I used the Canon EDSDK so I can't recall the details currently. But you are right for the reset trick. A lot of time I did need to restart the camera when I control it through my laptop though :)

    ReplyDelete