Canon Nikon 両対応 Cameralibの開発

バイナリを配布します

以前の記事で、Canon EOS SDKおよびNikon Imaging SDKをダウンロードしましたが、前者はEdsなんとかかんとかの嵐、後者はProperty and or Capability Get and Putの嵐で、極めて使いにくく、また誤りやすいので、両方のカメラをカバーするクラスライブラリwrapperともいふ)を作りましたので、公開します。一部メーカーさん提供のソースコードを修正して使っていますので、バイナリで供給します。どの程度のことができるのかをまず示します。

このようなフォームで、Captureで静止画を録り、フォームに表示、Stillでファイルとしてセーブ、Movieで動画をDurationで設定した時間(秒単位)で録画するミニマムなプログラムです。

先にコードを示しますが、前に投稿したEdsdkを直接的に操るコードと違って簡単至極です。

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include "cameralib.h"
#include <jpeg.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

Camera* camera;
extern int filecount;
int Live=0;


EdsError EDSCALLBACK ProgressFunc(EdsUInt32 inPercent, EdsVoid* inContext, EdsBool* outCancel)
{

	Form1->TransferProgress->Position = inPercent;
	return EDS_ERR_OK;
}

void UpdateProgressBar(unsigned long value)
{
	Form1->TransferProgress->Position = value;
}


//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	camera = new Camera();
	if( camera->TotalCameraCount > 0  ){
		Label1->Caption = camera->GetName();
		Movie->Enabled = true;
        Still->Enabled = true;
	}
	else
		Label1->Caption = "no cameras found";


}
//---------------------------------------------------------------------------

void __fastcall TForm1::CaptureClick(TObject *Sender)
{
 	void* data;
	long    size;

	filecount = 1;

	TMemoryStream* ImageStream = new TMemoryStream();

	camera->TakePictureToStream();


	data = camera->getbuffer();
	size = camera->getsize();

	ImageStream->WriteBuffer(data,size);
	ImageStream->Position = 0;

	Image1->Picture->LoadFromStream(ImageStream);
	//Image1->Refresh();
	delete ImageStream;

}
//---------------------------------------------------------------------------

void __fastcall TForm1::StillClick(TObject *Sender)
{
	camera->TakePictureToFile();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::MovieClick(TObject *Sender)
{
 	camera->RecordMovie();
	Sleep(1000*(StrToInt(Duration->Text)+1));
	camera->StopMovie();

}
//---------------------------------------------------------------------------

Unit1.cppはこれだけ。接続したカメラがNikonであっても、そのままで動きます。唯一

EdsError EDSCALLBACK ProgressFunc(EdsUInt32 inPercent, EdsVoid* inContext, EdsBool* outCancel)
{

	Form1->TransferProgress->Position = inPercent;
	return EDS_ERR_OK;
}

の部分だけが、EDSDKぽいですけど、これはForm1側にプログレスバーを表示するためにいたしかたないわけです。できたら隠蔽したいところです。まずカメラの宣言ですが、

#include "cameralib.h"

.......

camera = new Camera();

でおけです。続いて、

	if( camera->TotalCameraCount > 0  ){
		Label1->Caption = camera->GetName();
		Movie->Enabled = true;
        Still->Enabled = true;
	}
	else
		Label1->Caption = "no cameras found";

camera->TotalCameraCountで接続されていて認識されているカメラの総数が得られますから、1台以上接続されていたら、camera->GetName()で得られたカメラの名前をLabel1に表示します。以下シャッターを切り、得られた画像をImage1に表示するのは、

void __fastcall TForm1::CaptureClick(TObject *Sender)
{
 	void* data;
	long    size;

	filecount = 1;

	TMemoryStream* ImageStream = new TMemoryStream();

	camera->TakePictureToStream();


	data = camera->getbuffer();
	size = camera->getsize();

	ImageStream->WriteBuffer(data,size);
	ImageStream->Position = 0;

	Image1->Picture->LoadFromStream(ImageStream);
	//Image1->Refresh();
	delete ImageStream;

}

だけで済みますが、Image1のプロパティーを下図のようにセットしておくと画像の収まりが良いです。

これだけのために図を掲げるのも極めて面倒なのでコードで書いた方が簡単ですね。

Image1->Propertional = True;
Image1->Stretch = True;

ですね。

TMemoryStreamを用意して、camera->TakePictureToSteam()で内部バッファに取れている画像データの先頭アドレスをdata=camera->getbuffer()で得て、サイズsize=camera->getsize()で捉え、ImageStrem->WriteBuffer(data,size)で書き込みます。あとは、それをImage1に表示するだけです。画像をファイルとしてセーブするのは、

void __fastcall TForm1::StillClick(TObject *Sender)
{
	camera->TakePictureToFile();
}

これだけ。Durationから秒数を拾って、その秒数だけ動画を撮るのは、

void __fastcall TForm1::MovieClick(TObject *Sender)
{
 	camera->RecordMovie();
	Sleep(1000*(StrToInt(Duration->Text)+1));
	camera->StopMovie();

}

簡単ですよね。Nikon D7500を接続すると、

とカメラを認識しています。

ファイルへセーブ(Still)すると、

動画(movie)は、

となります。公開可能なCameralibのバイナリは、以下からダウンロードしてください。

“Cameralib 64” をダウンロード cameralib-1.zip 55.42 KB

これをどのように新規プログラムに組み込むかは、別記事で。

コメント