Taking picture with EDSDK and retrieving it immediately
For few days I've tried to retrieve the taken picture from camera. Today I found
EdsSetPropertyData(cRef, PropID_SaveTo, 0, 4, 2);
which doesn't save the picture to camera. But my problem is currently that I can't retrieve image from camera. My ObjectEventHandler will never be called (sometimes in initialization it will be called for previous pictures). Here is my caller (in main function):
Camera camera = new Camera();
Thread thread = new Thread(new ThreadStart(camera.DoThings));
thread.Start();
And here is my CC class (camera control)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EDSDKLib;
namespace CCCBSv2
{
class CC : EDSDK
{
IntPtr cRef;
// Initilizes, takes picture and uninitilizes
public void RunSeq()
{
uint err;
err = Initialize();
if (err != EDS_ERR_OK)
{
return;
}
err = TakePicture();
if (err != EDS_ERR_OK)
{
return;
}
Uninitilize();
}
public uint Initialize()
{
// err init
uint err;
// Initilize SDK.
// SDK initilizion is needed to use EDSDK functions
err = EdsInitializeSDK();
// In case of error pass it on...
if (err != EDS_ERR_OK)
{
return err;
}
// get first camera connected to computer
err = GetFirstCamera();
if (err != EDS_ERR_OK)
{
return err;
}
// Open session to camera
EdsOpenSession(cRef);
// Set object event handler, We need this event handler to retrieve pictures from camera
err = EdsSetObjectEventHandler(cRef, ObjectEvent_All, ObjectEventHandler, IntPtr.Zero);
if (err != EDS_ERR_OK)
{
return err;
}
// We don't want to save pictures to the camera so lets set save target to host
err = EdsSetPropertyData(cRef, PropID_SaveTo, 0, 4, 2);
return err;
}
// uninitilizes edsdk
public uint Uninitilize()
{
uint err;
err = EdsCloseSession(cRef);
if (err != EDS_ERR_OK)
{
return err;
}
err = EdsTerminateSDK();
return err;
}
// gets the first camera to cRef
private uint GetFirstCamera()
{
// Variable initilazions
IntPtr cameraList;
uint err;
int count;
// Get list of cameras;
err = EdsGetCameraList(out cameraList);
if (err != EDS_ERR_OK)
{
return err;
}
// Get count of cameras in list
err = EdsGetChildCount(cameraList, out count);
if (err != EDS_ERR_OK)
{
return err;
}
if (count == 0)
{
return EDS_ERR_DEVICE_NOT_FOUND;
}
// Get first camera to public cRef
err = EdsGetChildAtIndex(cameraList, 0, out cRef);
if (err != EDS_ERR_OK)
{
return er开发者_运维技巧r;
}
// release camera list
if (cameraList != null)
{
EdsRelease(cameraList);
}
// everything went just fine
return EDS_ERR_OK;
}
public uint ObjectEventHandler(uint inEvent, IntPtr inRef, IntPtr inContext){
switch (inEvent)
{
// in case of a download request
case ObjectEvent_DirItemRequestTransfer:
DownloadImage(inRef);
break;
default:
break;
}
return EDS_ERR_OK;
}
// Downloads the picture from camera's buffer to the computer
private uint DownloadImage(IntPtr dItem)
{
EdsDirectoryItemInfo dirInfo;
uint err;
IntPtr stream = new IntPtr();
err = EdsGetDirectoryItemInfo(dItem, out dirInfo);
if (err == EDS_ERR_OK)
{
err = EdsCreateFileStream(dirInfo.szFileName, EdsFileCreateDisposition.CreateAlways, EdsAccess.ReadWrite, out stream);
}
if (err == EDS_ERR_OK)
{
err = EdsDownload(dItem, dirInfo.Size, stream);
}
if (err == EDS_ERR_OK)
{
err = EdsDownloadComplete(dItem);
}
if (stream != null)
{
EdsRelease(stream);
}
return err;
}
// Takes picture
public uint TakePicture()
{
return EdsSendCommand(cRef, CameraCommand_TakePicture, 0);
}
}
}
You will need a Windows message loop to fetch and dispatch events. The object event handler should be called after you add this to main()
:
while(GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Also, remember to set PropID_SaveTo to SaveTo_Host. You can see my post here.
I am working on better Canon EOS Support for .NET. I call it Canon.Eos.Framework. I just added support for taking pictures and downloading them any path on your compuuter. This framework is still in Alpha Mode, but feel free to test.
My first guess is that you UnInitialize the driver too quickly, before the callback has a chance to be triggered.
TakePicture just tells the camera to take the picture, and you return more or less instantly to uninitialize the driver. But actually taking the picture involves moving mechanical parts around and may take half an eternity, and by the time the camera announces that it's done, there is no listener anymore to take the message.
精彩评论