Tuesday, January 22, 2008

Programming with the Canon Digital Camera Part 2

I got my Canon EOS Digital Software Development Kit (ED-SDK 2.1) back in December but have not gotten much time to experiment with it. I wrote some quick-and-dirty program today just to test out the different SDK function calls. I opted to test with my Canon EOS 400D instead of the Digital IXUS 400 primarily because the EOS Development Kit (EDK) already came with a C-Sharp wrapper called EDSDK.cs. So I didn't have to download some other 3rd party library wrapper just to integrate with the CD-SDK.

The C Sharp wrapper bundled with the EDK is pretty basic. In fact, I would not really call it a class in the OOP sense. Its more of like a traditional C struct. It enumerates all the different constants and data structures supported by the EDK, which is a big help since I would not want to re-type that. The development library can be either statically linked through the provided EDSDK.lib file, or by dynamic linking by referring to the EDSDK.dll. The C Sharp class file uses the latter method (since I don't think there is any way of linking directly to a .lib file with C#). The EDSDK.cs wrapper file provides the convenient function prototypes already also.

The program flow is very straightforward. You call EdsInitializeSDK() to startup the library and EdsTerminateSDK() to shut it down. Then in-between that's where you do all the neat stuffs -- like query the camera for its properties and settings; modify the settings; take a picture; go through the camera's storage system and retrieve images. The EDK pretty much lets you change all the settings that can be modified -- the ISO speed, AE mode, aperture, shutter speed, JPEG quality/compression level, and so much more. Anything that you can set using the camera's LCD menu, can be programmatically set as well. The EDK provides you with functions to lock the User Interface so that while the application is in control of the camera, it cannot be manually overridden by a human operator.

I think in theory you can connect multiple cameras to a PC via the provided USB cable and control them from a single application (this setup of EOS cameras is pretty amazing). The EDK just mentions some notes about concurrency issues that might cause problems. In any case, I have no plans of attaching more than one camera so that should not be an issue. The SDK does provide you with functions to list the cameras attached, or are available, and lets you select which one you want to work with. Once you've selected your camera, you would open a session with it by calling EdsOpenSession(). Then you would use the EdsSendCommand() mainly to do everything else like doing a remote capture.

I've gotten as far as the following:
  1. Initialize the SDK
  2. Enumerate the cameras attached and select the 1st one (my EOS 400D in this case)
  3. Open a session with the camera
  4. Retrieve its settings and properties
  5. Perform a remote capture (aka. Take a Picture)
  6. Close the camera session
  7. Terminate the SDK

The images taken by step 5 currently remains on the camera. I have to do more experimentation next time on how to do image transfers from the camera to the PC. Of course, the SDK provides all of those functions as well. Its just a matter of figuring out how to use them correctly. I will need to define postback functions for sure. For now, I'm purely doing synchronous programming. However, the programming model that the Canon EDK uses is asynchronous and postback-based.


pathfinder said...

Could you provide step by step instructions on how you used the SDK to get this far? I have the Canon EDSK but not sure how to use it in C# / VS 2005.

Dick Chiang said...

Assuming you have EDSDK 2.1 (the same version I'm using), you would do something like: 1. Create a new project under VS2005; 2. Copy/include a copy of the EDSDK.cs class file that came with the EDSDK (I appears under the SAMPLE\CSharp\COMMON on my installation) into your project; 3. Copy all the DLL's found under the EDSDK\DLL folder onto your project output folder (not sure if there's a simpler way to do this by specifying the path where to look for the DLL's); 4. write your program to access the SDK via the EDSDK.cs class file that I mentioned in item 2.

pathfinder said...

Looks like I am a bit further; however, could you provide an example of how you are initializing, listing camera, opening the camera from the list, and then terminating the API...

I am trying to create a form that initialize the API at the start, lists attached camera, and allows the user to select it, and then terminates... I think if I can get this far I would be fine... Just not sure if I am calling the wrapper / class properly "get errors"... Any help would be great!

Paul said...

Can you put some example code in your blog as well? I can't get the C# wrapper to work.
Thanks in advance!

epatnor said...

Hi Dick,

I also would be very interested in having a look at your source code, if that's possible. My application can read some properties from the 40D I'm using, but my attempts to take a picture fails miserably.

This would be most helpful if you have the time and/or want to help out a little. Thanks! //Patrik (epatnor_at_gmail_dot_com)

Dick Chiang said...

Hi Patrik, emailing you some c# code

charles said...

Hi Dick,

I also am very interested in having a look at your source code, if that's possible. I tried the vb example from the sample code in the ESDK, but it failed. The the vc sample could cannot detect the cameer.

Appreciate so much if you could have time to give a hand! //Ben

Michael Murdock said...

Could you send me your code as well?
I would really appreciate it!!!

MichaelcMurdock xATx Yahoo_dot_com

Eric said...

Hi Dick

I am very interested to have a look at your source code, if you can send it to my email (ericleunghk@hotmail.com). I tried the CSharp example from the sample code in the ESDK, but it failed.

Appreciate so much. Hope you could have time to give a hand!

My email: ericleunghk@hotmail.com

Dick Chiang said...

I've decided to just upload the source code since I'm starting to get several requests already for it.


Feel free to download at your own risk. No additional support will come from me. :)

jsidhu said...

Right on, I'm about to get started on a project and this should be a huge help. Thanks for sharing!

nvm said...

thank you, it works great.

Stuart said...

Hi. I am looking for someone to develop a class wrapper for VB6 using the Canon ED-SDK.

I only require the basic functions to be exported:
- Connect
- TakePicture
- RetrieveLastPicture
- SetFocus

If anyone can help me with this, it can be a paid project, through rentacoder or direct.


Jiri Stybnar said...

I work with pair of Rebel XTi or Rebel XSi. Under Windows XP, everything works fine. Under Vista, I can't get control of the second camera, it always sends commands to the first camera. Did anyone make 2-camera system working under Vista? Canon tech support is not willing to make any comments regarding SDK. Jiri

Patrick said...

Awesome! Thanks.

Crap said...

Hello Dick,

Awesome app.
The objectEventHandler never fires. Can you help me in retrieving the last taken picture? I'm using an EOS450D btw.


Dick Chiang said...

Sorry, but I never got around that far. :P I only reached up to the point of taking the photo (but it stays in the CF memory). I haven't tried extracting images from the CF.

Dick Chiang said...

An alternative way of working with Canon EOS cameras without the use of an SDK is discussed here.

vissu said...

Hi I am also using EDSDK 2.1 for controlling the Canon Rebel XSI Digital Camera.I have issues in taking two captures in a single session with less time delay.So I would be thankful to you if you can help me in solving this.

Yu said...

Hi, how could we go through the camera's storage system and retrieve images?

Wouild it be possible to past some code?

The Camea is setup to take a picturea at every 5 minutes and the c# program need to copy and delete the pictures from the cameras at certain intervals.


CMDeveloper said...

I wanted to know if you could please post or email me your sample code.

Thank you


Dick Chiang said...

CMDeveloper, you have to request for the SDK directly from Canon. The terms of the license prevents me from giving you my copy.

Raum said...

Jiri, I am getting the same problem with windows 7. The SDK will see only the first camera although I select reference of the second camera. Were you able to resolve this issue? I am using EDSDK 2.5.2

Hau said...

Hi Dick Chiang!
I was wondering if you have the EDSDK working with version 2.8 in CS or VB? The ones given by canon simply dont work .

Dick Chiang said...

Sorry, but I haven't taken a look at the SDK for some time. I stopped at 2.1. :P

Drew Vinciguerra said...

Awesome sample. It really helped me. At first I was getting the EdsOpenSession failure with your code so I updated the canon SDK to 2.10 and it started to work. Thanks!

Daniel said...

The reason the objectEventHandler never fires is because you have to tell the camera to store to the host computer:

EdsInt32 value = kEdsSaveTo_Host;
EdsSetPropertyData(Camera_Handle, kEdsPropID_SaveTo, 0, sizeof(value), &value);

You will also need to tell the camera the available space or it will not store as this defaults to 0 bytes:

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

Once that is done, the callback will work as expected. This is all from the SDK documentation.

Kacper Barski said...

Hi Dick Chiang, I know it's an old thread but I would really appreciate if you can e-mail me your source code if you still have it. The link that you've put up is broken, after all that was 8 years ago. Thanks in advance, my e-mail is: 17barski@gmail.com

Dick Chiang said...

You need the Canon EDSDK for this to work. Were you able to request a copy from Canon already?

Kacper Barski said...

Yes, I have the Canon SDK with the header files, library files and dll's, just not sure how to put it all together in visual studio. Thanks for the quick reply.