开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜