佳能EDSDK 13.11.10无法保存到主机PC

问题描述

我正在用Canons EDSDK实施远程相机控制应用程序。我的相机是佳能PowerShot SX 70 HS。到目前为止,除了将拍摄的图片保存到主机PC的功能之外,其他一切似乎都可以正常工作。

我对所需工作流程的理解如下:

  1. 初始化相机
  2. 重写对象事件处理程序并传递给EdsObjectEventHandler,以修改“保存图像行为”
  3. 拍照
  4. 关闭流并销毁所有对象。

我已经修改了自己的初始版本,并尝试了这些线程中提供的解决方案:

canon EDSDK saving image in my PC

Canon SDK - Downloading image to host PC

下面是代码...

...对于第一个线程:

#include <iostream>

#include "EDSDK.h"
#include "EDSDKTypes.h"
#include "EDSDKErrors.h"

EdsError getFirstCamera(EdsCameraRef* camera);
EdsError downloadImage(EdsDirectoryItemRef directoryItem);
EdsError EDSCALLBACK handleStateEvent(EdsStateEvent event,EdsUInt32 parameter,EdsVoid* context);
EdsError EDSCALLBACK handleObjectEvent(EdsObjectEvent event,EdsBaseRef object,EdsVoid* context);
EdsError EDSCALLBACK handlePropertyEvent(EdsPropertyEvent event,EdsPropertyID property,EdsUInt32 inParam,EdsVoid* context);


int main(int argc,char** argv)
{
    EdsError err;
    EdsCameraRef camera = NULL;
    bool isSDKLoaded = false;
    EdsCapacity capacity = { 0x7FFFFFFF,0x1000,1 };
    EdsInt32 saveTarget = kEdsSaveTo_Host;

    // Initialize SDK
    err = EdsInitializeSDK();
    if (err == EDS_ERR_OK)
    {
        isSDKLoaded = true;
    }

    // Get first camera
    if (err == EDS_ERR_OK)
    {
        err = getFirstCamera(&camera);
    }


    // Open session with camera
    err = EdsOpenSession(camera);

    // Set event handler
    if (err == EDS_ERR_OK)
        err = EdsSetObjectEventHandler(camera,kEdsObjectEvent_All,handleObjectEvent,NULL);
    
    if (err == EDS_ERR_OK)
        err = EdsSetPropertyEventHandler(camera,kEdsPropertyEvent_All,handlePropertyEvent,NULL);
    
    if (err == EDS_ERR_OK)
        err = EdsSetCameraStateEventHandler(camera,kEdsStateEvent_All,handleStateEvent,NULL);

    err = EdsSetPropertyData(camera,kEdsPropID_SaveTo,4,&saveTarget);

    err = EdsSetCapacity(camera,capacity);

    ///// Take picture
    err = EdsSendCommand(camera,kEdsCameraCommand_TakePicture,0);
    ////

    // Close session with camera
    if (err == EDS_ERR_OK)
    {
        err = EdsCloseSession(camera);
    }

    // Release camera
    if (camera != NULL)
    {
        EdsRelease(camera);
    }

    // Terminate SDK
    if (isSDKLoaded)
    {
        EdsTerminateSDK();
    }
}


EdsError EDSCALLBACK handleObjectEvent(EdsObjectEvent event,EdsVoid* context)
{
    std::cout << "I'm in the callback-function!!!\n"; // Never shows!
    EdsError err = EDS_ERR_OK;

    switch (event)
    {
    case kEdsObjectEvent_DirItemRequestTransfer:
        err = downloadImage(object);
        break;
    default:
        break;
    }

    // Object must be released
    if (object) {
        err = EdsRelease(object);
    }
    return err;
}

EdsError EDSCALLBACK handlePropertyEvent(EdsPropertyEvent event,EdsVoid* context)
{
    return EDS_ERR_OK;
}

EdsError EDSCALLBACK handleStateEvent(EdsStateEvent event,EdsVoid* context)
{
    return EDS_ERR_OK;
}


EdsError getFirstCamera(EdsCameraRef* camera)
{
    EdsError err;
    EdsCameraListRef cameraList = NULL;

    err = EdsGetCameraList(&cameraList);
    err = EdsGetChildAtIndex(cameraList,camera);
    return err;
}

EdsError downloadImage(EdsDirectoryItemRef directoryItem)
{
    EdsError err = EDS_ERR_OK;
    EdsStreamRef stream = NULL;
    // Get directory item information
    EdsDirectoryItemInfo dirItemInfo;
    err = EdsGetDirectoryItemInfo(directoryItem,&dirItemInfo);

    // Create file stream for transfer destination
    if (err == EDS_ERR_OK)
    {
        err = EdsCreateFileStream(dirItemInfo.szFileName,kEdsFileCreateDisposition_CreateAlways,kEdsAccess_ReadWrite,&stream);
    }
    // Download image
    if (err == EDS_ERR_OK)
    {
        err = EdsDownload(directoryItem,dirItemInfo.size,stream);
    }
    // Issue notification that download is complete
    if (err == EDS_ERR_OK)
    {
        err = EdsDownloadComplete(directoryItem);
    }
    // Release stream
    if (stream != NULL)
    {
        EdsRelease(stream);
        stream = NULL;
    }
    return err;
}

第二个线程:

#include <iostream>

#include "EDSDK.h"
#include "EDSDKTypes.h"
#include "EDSDKErrors.h"

static EdsError EDSCALLBACK handleObjectEvent(EdsObjectEvent event,EdsVoid* context)
{
    std::cout << "I'm in the callback-function!!!\n";  // NEVER PRINTS!
    EdsError err = EDS_ERR_OK;
    if (event == kEdsObjectEvent_DirItemRequestTransfer)
    {
        EdsStreamRef stream = NULL;
        EdsDirectoryItemInfo dirItemInfo;
        err = EdsGetDirectoryItemInfo(object,&dirItemInfo);
        err = EdsCreateFileStream(dirItemInfo.szFileName,&stream);
        err = EdsDownload(object,stream);
        err = EdsDownloadComplete(object);
        EdsRelease(stream);
        stream = NULL;
    }
    if (object)
        EdsRelease(object);

    return err;
}

void TakePhoto(EdsCameraRef camera)
{
    EdsError err = EDS_ERR_OK;
    EdsCameraListRef cameraList = NULL;
    EdsUInt32 count = 0;

    err = EdsInitializeSDK();
    err = EdsGetCameraList(&cameraList);
    err = EdsGetChildCount(cameraList,&count);
    if (count > 0)
    {
        err = EdsGetChildAtIndex(cameraList,&camera);
        cameraList = NULL;
        err = EdsSetObjectEventHandler(camera,NULL);
        err = EdsOpenSession(camera);
        err = EdsSendCommand(camera,0);
    }
}

void Close(EdsCameraRef camera)
{
    EdsError err = EdsCloseSession(camera);
    EdsRelease(camera);
    EdsTerminateSDK();
}

int main() {
    EdsCameraRef camera = NULL;
    TakePhoto(camera);
    Close(camera);
    return 0;
}

但是,如前所述:在主机PC上找不到图像。如果我提供了EdsCreateFileStream的完整路径,这不会改变。将图像保存在二进制文件所在的目录中的默认行为(使用dirItemInfo.szFileName作为EdsCreateFileStream的第一个参数也不起作用。

那可能是因为我尝试的最新解决方案是从2014年开始,并且API同时进行了更改。我也在GitHub上寻找实现,并在官方手册中找到了,但是对我来说这两者都不是很透明。

真正令我困惑的是,当我尝试进行printf样式的调试(在handleObjectEvent内添加输出时,打印内容从未显示出来!这是由于该函数的回调性质吗?必须承认,我以前没有使用过回调。

下面提供的所有版本均已构建并执行。我也可以在这里单击摄像机,但是如前所述:我在磁盘上找不到图像!

是否执行了回调?为何印刷品从不显示?我最终如何修改程序以将图像保存到磁盘?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)