写真を撮って、EDSDK 2.8を使用して画像をPCに直接保存します
質問
EDSDK 2.8は初めてです
現時点では、私のプログラムは写真を撮ることができます。ただし、写真を撮ると、その写真は一時的にキヤノンカメラのバッファーに保存されます。ディレクトリをPCに保存する方法を知りたいですか?
誰かがアイデアを持っていますか?または、C#またはvb.netのサンプルコード?
解決
これが私がやったことです:
まず、オブジェクトが作成されたときにコールバックイベントに登録する必要があります(つまり、写真)。これを作成したRegisterEventsメソッドでこれを行いました。
// Register OBJECT events
edsObjectEventHandler = new EDSDK.EdsObjectEventHandler(objectEventHandler);
error = EDSDK.EdsSetObjectEventHandler(this.CameraDevice,
EDSDK.ObjectEvent_All, edsObjectEventHandler, IntPtr.Zero);
if (EDSDK.EDS_ERR_OK != error)
{
throw new CameraEventRegistrationException("Unable to
register object events with the camera!", error);
}
objectEventHandler
写真が作成されたときに呼び出される方法です。
この方法は、APIによって決定されるインターフェイスに準拠する必要があります。その方法の実装の例は次のとおりです。
/// <summary>
/// Registered callback function for recieving object events
/// </summary>
/// <param name="inEvent">Indicate the event type supplemented.</param>
/// <param name="inRef">Returns a reference to objects created by the event.</param>
/// <param name="inContext">Passes inContext without modification</param>
/// <returns>Status 0 (OK)</returns>
private uint objectEventHandler(uint inEvent, IntPtr inRef, IntPtr inContext)
{
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;
}
この例では、私は向きを変えて、ストリームオブジェクトへの参照がある独自のイベントを生み出します。これは、次のコードによって処理されます。
/// <summary>
/// Gets a photo or video clip from the camera
/// </summary>
/// <param name="directoryItem">Reference to the item that the camera captured.</param>
/// <returns></returns>
private CapturedItem getCapturedItem(IntPtr directoryItem)
{
uint err = EDSDK.EDS_ERR_OK;
IntPtr stream = IntPtr.Zero;
EDSDK.EdsDirectoryItemInfo dirItemInfo;
err = EDSDK.EdsGetDirectoryItemInfo(directoryItem, out dirItemInfo);
if (err != EDSDK.EDS_ERR_OK)
{
throw new CameraException("Unable to get captured item info!", err);
}
// Fill the stream with the resulting image
if (err == EDSDK.EDS_ERR_OK)
{
err = EDSDK.EdsCreateMemoryStream((uint)dirItemInfo.Size, out stream);
}
// Copy the stream to a byte[] and
if (err == EDSDK.EDS_ERR_OK)
{
err = EDSDK.EdsDownload(directoryItem, (uint)dirItemInfo.Size, stream);
}
// Create the returned item
CapturedItem item = new CapturedItem();
if (err == EDSDK.EDS_ERR_OK)
{
IntPtr imageRef = IntPtr.Zero;
err = EDSDK.EdsCreateImageRef(stream, out imageRef);
if (err == EDSDK.EDS_ERR_OK)
{
EDSDK.EdsImageInfo info;
err = EDSDK.EdsGetImageInfo(imageRef, EDSDK.EdsImageSource.FullView, out info);
if (err == EDSDK.EDS_ERR_OK)
{
item.Dimensions = new com.waynehartman.util.graphics.Dimension((int)info.Width, (int)info.Height);
EDSDK.EdsRelease(imageRef);
}
}
}
if (err == EDSDK.EDS_ERR_OK)
{
byte[] buffer = new byte[(int)dirItemInfo.Size];
GCHandle gcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr address = gcHandle.AddrOfPinnedObject();
IntPtr streamPtr = IntPtr.Zero;
err = EDSDK.EdsGetPointer(stream, out streamPtr);
if (err != EDSDK.EDS_ERR_OK)
{
throw new CameraDownloadException("Unable to get resultant image.", err);
}
try
{
Marshal.Copy(streamPtr, buffer, 0, (int)dirItemInfo.Size);
item.Image = buffer;
item.Name = dirItemInfo.szFileName;
item.Size = (long)dirItemInfo.Size;
item.IsFolder = Convert.ToBoolean(dirItemInfo.isFolder);
return item;
}
catch (AccessViolationException ave)
{
throw new CameraDownloadException("Error copying unmanaged stream to managed byte[].", ave);
}
finally
{
gcHandle.Free();
EDSDK.EdsRelease(stream);
EDSDK.EdsRelease(streamPtr);
}
}
else
{
throw new CameraDownloadException("Unable to get resultant image.", err);
}
}
他のヒント
私はカメラにメモリカードがなく、Take Pictureコマンドが送信された後にイメージをホストコンピューターに転送したいという点で同じことをしています。これが私のために働いたものです ObjectEventHandler
CANON EOS50Dにメモリカードがインストールされていない場合、コールバックが呼び出されます。
EdsUInt32 setsaveto = kEdsSaveTo_Both;
err = EdsSetPropertyData(camera, kEdsPropID_SaveTo, 0, sizeof(setsaveto), &setsaveto);
vaila、コールバックが呼び出され、その後、 getCapturedItem()
ウェインが以前の投稿に投稿したように機能します。
所属していません StackOverflow