Search code examples
c++visual-studioevent-handlingcanon-sdk

Canon SDK fails to download picture from camera


Below C++ with Canon SDK is about 80% working. It can set exposure time, set ISO, take pictures and save it to camera's SD card. However, after picture is taken, the code cannot save picture to my computer. Code never reach "EdsError EDSCALLBACK handleObjectEvent...". For some reason, my camera seem can not trigger that even in my software. What could be wrong with my code?

My camera is EOS-80D, SDK version is "EDSDK-v13-12-1_for_Windows", my PC is using Windows 7 with Visual Studio 2019 Preview version.

I am pretty new to VC++, so please make correction on my code directly if possible. Really appreciate if any one can provide some hints. Thanks.

#include <iostream>
#include "EDSDK.h"
#include "EDSDKErrors.h"
#include "EDSDKTypes.h"
#include <thread>
#include <chrono>
#include <string>

using namespace std;


void wait_ms(int t) {
    this_thread::sleep_for(chrono::milliseconds(t));
}

void download_img(EdsBaseRef& object, EdsVoid*& context)
{
    cout << "I am in download_img()" << endl;
    const char* directory = "C:/Test.jpg";
    EdsStreamRef stream = NULL;
    EdsDirectoryItemInfo dirItemInfo;
    EdsGetDirectoryItemInfo(object, &dirItemInfo);
    EdsCreateFileStream(directory, kEdsFileCreateDisposition_CreateAlways, kEdsAccess_ReadWrite, &stream);
    EdsDownload(object, dirItemInfo.size, stream);
    EdsDownloadComplete(object);
    EdsRelease(stream);
    stream = NULL;
    if (object)
        EdsRelease(object);
}

EdsError EDSCALLBACK handleObjectEvent(EdsObjectEvent event, EdsBaseRef object, EdsVoid* context)
{
    cout << "I am in EDSCALLBACK()." << endl;
    download_img(object, context);
    return EDS_ERR_OK;
}

int init_camera(EdsCameraRef& camera)
{
    cout << "I am in init_camera()." << endl;
    EdsError err = 0;
    EdsCameraListRef cameraList = NULL;
    EdsUInt32 count = 0;
    camera = NULL;

    err = EdsInitializeSDK();
    err = EdsGetCameraList(&cameraList);
    err = EdsGetChildCount(cameraList, &count);

    if (count > 0){
        err = EdsGetChildAtIndex(cameraList, 0, &camera);
        EdsRelease(cameraList);
    }
    else {
        cout << "Camera is NOT detected during init_camera()!!" << endl;
        return 0; //Fail initialization
    }

    EdsSetObjectEventHandler(camera, kEdsObjectEvent_DirItemCreated, handleObjectEvent, NULL);
    EdsSendStatusCommand(camera, kEdsCameraStatusCommand_UIUnLock, 0);

    cout << "Camera has been detected during init_camera()!!" << endl;
    return 1; //Initialization is completeced     
}

void update_data(EdsCameraRef camera)
{
    EdsOpenSession(camera);
    EdsCloseSession(camera);
}

void take_one_bulb_photo(EdsCameraRef camera)
{
    EdsOpenSession(camera);
    cout << endl << "shoot one image" << endl;
    int ISO_factor = 98; // ISO=1000    
    EdsSetPropertyData(camera, kEdsPropID_ISOSpeed, ISO_factor, sizeof(ISO_factor), &ISO_factor);
    int Exp_factor = 110; // 125th
    EdsSetPropertyData(camera, kEdsPropID_Tv, Exp_factor, sizeof(Exp_factor), &Exp_factor);
    EdsSendCommand(camera, kEdsCameraCommand_TakePicture, 0); //page 40
    EdsCloseSession(camera);
}

void dispose(EdsCameraRef camera)
{
    EdsCloseSession(camera);
    EdsRelease(camera);
    EdsTerminateSDK();
}

int main() {
    EdsCameraRef camera;
    int ini_result = init_camera(camera);
    if (ini_result == 1) {take_one_bulb_photo(camera);}
    else {cout << endl << "Fail camera initialization!" << endl;}
    dispose(camera);
    update_data(camera);
    return 0;
}

Solution

  • Within take_one_bulb_photo() function. Before the last line "EdsCloseSession(camera);" Add below code; such as

        MSG msg;
        GetMessage(&msg, NULL, NULL, NULL);
        TranslateMessage(&msg); 
        DispatchMessage(&msg);
        GetMessage(&msg, NULL, NULL, NULL);
        TranslateMessage(&msg); 
        DispatchMessage(&msg);
        GetMessage(&msg, NULL, NULL, NULL);
        TranslateMessage(&msg); 
        DispatchMessage(&msg);
        GetMessage(&msg, NULL, NULL, NULL);
        TranslateMessage(&msg); 
        DispatchMessage(&msg);
    

    It fix my issue.

    Above solution is inspired by: Canon sdk internal error at edsDownload