2012-12-02 21 views
7

Tôi đã cố gắng thực hiện công việc này một thời gian ... đọc rất nhiều bài đăng nhưng không ai trong số họ có thể khắc phục vấn đề này.C# Canon SDK: Không gọi lại sau CameraCommand_TakeẢnh

Tôi đang kết nối với EOS 550D bằng Canon SDK. Tôi đang chạy 64bit win7 và Visual Studio C# 2010.

Những gì tôi làm từng bước là:

-> 0 Init SDK

err = EDSDK.EdsInitializeSDK(); 

-> 1 Lấy danh sách camera

err = EDSDK.EdsGetCameraList(out cameraList); 

-> 2 Bắt con đếm

err = EDSDK.EdsGetChildCount(cameraList, out cameraCount); 

-> 3 Nếu có một đứa trẻ, có đứa con đầu lòng

err = EDSDK.EdsGetChildAtIndex(cameraList, 0, out cameraDev); 

-> 4 khai mạc một phiên

err = EDSDK.EdsOpenSession(cameraDev); 

-> 5 Kể sdk để lưu hình ảnh tại địa phương

IntPtr saveTo = (IntPtr)EDSDK.EdsSaveTo.Host; 
err = EDSDK.EdsSetPropertyData(cameraDev, EDSDK.PropID_SaveTo, 0, 4, saveTo); 

-> 6 Đặt công suất khả dụng trên máy chủ

EDSDK.EdsCapacity capacity = new EDSDK.EdsCapacity(); 

if (err == EDSDK.EDS_ERR_OK) 
{ 
    capacity.NumberOfFreeClusters = 0x7FFFFFFF; 
    capacity.BytesPerSector = 0x1000; 
    capacity.Reset = 1; 
    err = EDSDK.EdsSetCapacity(cameraDev, capacity); 
} 

-> 7 Registring Nhà nước sự kiện Handler

err = EDSDK.EdsSetCameraStateEventHandler(cameraDev, EDSDK.StateEvent_All, stateEventHandler, new IntPtr(0)); 

-> 8 Registring Object Event Handler

EDSDK.EdsObjectEventHandler edsObjectEventHandler = new EDSDK.EdsObjectEventHandler(objectEventHandler); 
       err = EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, edsObjectEventHandler, IntPtr.Zero); 

....

Tôi không nhận được bất kỳ lỗi khi làm điều này, tất cả dường như là tốt.

Dưới đây là Handler của tôi

private uint objectEventHandler(uint inEvent, IntPtr inRef, IntPtr inContext) 
    { 
     Console.WriteLine("HALLLOOOOOOOOOO"); 
     switch (inEvent) 
     { 
      case EDSDK.ObjectEvent_DirItemCreated: 
       //this.invokeNewItemCreatedEvent(new NewItemCreatedEventArgs(getCapturedItem(inRef))); 
       Console.WriteLine("Directory Item Created"); 
       break; 
      case EDSDK.ObjectEvent_DirItemRequestTransfer: 
       Console.WriteLine("Directory Item Requested Transfer"); 
       break; 
      default: 
       Console.WriteLine(String.Format("ObjectEventHandler: event {0}, ref {1}", inEvent.ToString("X"), inRef.ToString())); 
       break; 
     } 

     return 0x0; 
    } 








    public uint stateEventHandler(uint inEvent, uint inParameter, IntPtr inContext) 
    { 
     Console.WriteLine("stateEventHandler " + inEvent); 
     switch (inEvent) 
     { 
      case EDSDK.StateEvent_JobStatusChanged: 
       Console.WriteLine(String.Format("There are objects waiting to be transferred. Job status {0}", inParameter)); 
       break; 

      case EDSDK.StateEvent_ShutDownTimerUpdate: 
       if (inParameter != 0) 
        Console.WriteLine(String.Format("shutdown timer update: {0}", inParameter)); 
       break; 

      case EDSDK.ObjectEvent_DirItemRequestTransfer: 
       //WHAT I NEED!!! 
       Console.WriteLine("Hallo DirItemRequestTransfer"); 
       //DownloadImage(obj); 
       break; 


      default: 
       Console.WriteLine(String.Format("StateEventHandler: event {0}, parameter {1}", inEvent, inParameter)); 
       break; 
     } 
     return 0; 
    } 

...

Vì vậy, bây giờ vấn đề của tôi là không ai trong số các handler được bao giờ gọi. Không biết tại sao, tôi searche các fpr ròng khá nhiều thời gian, cố gắng tiếp cận khác nhau nhưng đã không nhận được cuộc gọi lại ...

Dưới đây là phương pháp của tôi gọi lệnh chụp ảnh:

public void takePic() 
    { 
     if (cameraOpened) 
     { 
      Console.WriteLine("taking a shot"); 

      err = EDSDK.EdsSendCommand(cameraDev, EDSDK.CameraCommand_TakePicture, 0); 
      if (err != EDSDK.EDS_ERR_OK) 
       Console.WriteLine("TakeCommand Error: " + err.ToString()); 

      Console.WriteLine("Finished taking a shot"); 

     } 
    } 

Có lẽ ai đó có một ý tưởng những gì tôi có thể cố gắng để làm cho công việc này?

Cảm ơn trước!

Trân trọng, Tobias

Trả lời

1

Tôi đang sử dụng ++ phiên bản C của SDK cho một số tháng nay.

Sau khi quét nhanh, tất cả có vẻ ổn trong mã của bạn.Tôi không chắc chắn về C# thu gom rác/scoping trong ví dụ này, nhưng bạn muốn chắc chắn rằng trình xử lý của bạn vẫn "xung quanh" sau khi bạn đã đặt chúng.

Ngoài ra, đối với tham số EdsContext cuối cùng, tôi sử dụng con trỏ đến lớp chứa của tôi thay vì con trỏ bằng không.

err = EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, edsObjectEventHandler, IntPtr.Zero); 

Nếu bạn không cần chứa trình xử lý sự kiện trong lớp, điều này có thể không phải là vấn đề, nhưng có lẽ đa luồng trong ứng dụng của bạn sẽ khiến bạn khó chịu. Từ hướng dẫn sử dụng EDSDK:

Chỉ định thông tin ứng dụng được chuyển bằng chức năng gọi lại. Bất kỳ dữ liệu cần thiết cho ứng dụng của bạn có thể được thông qua. Trong môi trường đa luồng, chức năng gọi lại được thực hiện bởi một chuỗi dành riêng cho sự kiện. Sử dụng nó một cách thích hợp, như trong việc chỉ định con trỏ này để truyền dữ liệu đến các luồng giao diện người dùng. Chỉ định một con trỏ NULL nếu nó không cần thiết.

Bạn cũng có thể thử và thêm một handler handlePropertyEvent cần kích hoạt vào những thay đổi trong cân bằng trắng/chuyển sang LiveView vv

6

Tôi biết các tài liệu SDK nói rằng các chức năng gọi lại sẽ được thực hiện trong chủ đề khác , nhưng đối với tôi, sử dụng SDK 2.11 trong Windows, các cuộc gọi lại luôn luôn xảy ra trên luồng chính và dường như được gửi qua tin nhắn Windows. Điều này có nghĩa rằng nếu bạn không có một máy bơm tin nhắn, bạn sẽ không nhận được cuộc gọi lại. Nếu ứng dụng của bạn là một ứng dụng C# GUI, bạn nên có một máy bơm tin nhắn, nhưng nếu đó là một ứng dụng giao diện điều khiển có thể bạn sẽ không có, vì vậy hãy thử tự bơm các thông báo sau khi gửi lệnh TakePicture. Bạn có thể sử dụng Application.Run nhưng bạn sẽ cần phải gọi Application.Exit ở đâu đó hoặc vòng lặp tin nhắn của bạn sẽ không bao giờ thoát (ví dụ: bạn có thể gọi nó sau khi tải hình ảnh từ máy ảnh).

+0

này đã làm cho tôi; Tôi đã cắm nó trong hai ngày, vì ứng dụng đang chạy phía sau máy chủ web Nancy tự lưu trữ như một dịch vụ topshelf, các đại biểu được viết bằng F # và xếp hàng các yêu cầu máy ảnh trong một 'MailboxProcessor', vì vậy có một triệu biến, hóa ra đây là những gì đã sửa nó. Cụ thể, tôi đã phải gọi 'InitialzeSDK' và' SetCameraAddedHandler' trong một chuỗi * mới * và gọi 'Application.Run()' ở cuối chuỗi. –

+0

bạn có thể vui lòng cung cấp một số ví dụ về mã không? –

+1

Rất tốt để tìm ra Sam! –

0

Tôi đang kết nối với EOS 550D bằng Canon SDK. Tôi đang chạy win7 64bit và Visual Studio C# 2010.

Vấn đề của bạn ở đó: SDK Canon được biên dịch cho X86. Đừng nhìn xa hơn! Bạn phải thay đổi kiến ​​trúc đích của bạn.

+0

Đây không phải là vấn đề. Chắc chắn, dự án C# nên được đặt thành x86 thay vì x64 hoặc CPU bất kỳ vì thư viện gốc là x86, nhưng sẽ có vô số các vấn đề khác nếu được đặt không chính xác. Trong trường hợp này, tôi chắc chắn rằng câu trả lời của tôi là câu trả lời. – Sam

0

Cách bạn đăng ký sự kiện đối tượng không thực sự đăng ký bất kỳ thứ gì. Đây là cách tôi làm điều đó và nó hoạt động tốt:

event EDSDK.EdsObjectEventHandler SDKObjectEvent; 

void Init(IntPtr cameraDev) 
{ 
    SDKObjectEvent += new EDSDK.EdsObjectEventHandler(objectEventHandler); 
    EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, SDKObjectEvent, IntPtr.Zero); 
} 

Cùng nguyên tắc đi cho EdsStateEventHandler, EdsPropertyEventHandler và EdsCameraAddedHandler (và một chút khác nhau nhưng vẫn có một sự kiện EdsProgressCallback)

Kind coi

+1

Cách anh ta đặt trình xử lý sự kiện là tốt.Anh ấy đang làm điều tương tự như bạn, trên thực tế, ngoại trừ việc bạn đang định tuyến trình xử lý sự kiện của mình thông qua một đối tượng sự kiện riêng biệt (có lẽ không cần thiết). – Sam

Các vấn đề liên quan