C++ Linux下通过USB控制Nikon相机拍照和抓取照片
前段时间,需要在Linux下通过USB抓取Nikon相机拍摄的照片,但是Nikon相机提供的SDK只支持Windows和MacOS,所以在网上找了开源的库——libgphoto2。
libgphoto2号称支持2300中相机,包括Canon、Nikon、Sony,和各种型号的手机。
下载地址
编译和安装
libgphoto2的编译和安装过程和简单,中间提示缺什么就装上。编译的时候要注意查看依赖项,根据自己的需要选择安装(比如libusb)。
装好libgphoto2后,可以编译和安装gphoto2。gphoto2是使用libgphoto2编写的简单的命令行工具,方便调试设备和在其基础上编写自己的程序。
代码编写
头文件
头文件很简单,声明自己的函数:
#ifndef NIKONCTRL_H
#define NIKONCTRL_H
class NikonCtrl
{
public:
NikonCtrl();
bool Detect();
void Trigger();
void Download(const char* file_name);
int Capture(const char* file_name);
};
#endif // NIKONCTRL_H
cpp文件
cpp文件根据gphoto2的代码改写:
#include "nikonctrl.h"
#include <sys/time.h>
#include <sys/unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
extern "C" {
#include <gphoto2/gphoto2-port-info-list.h>
#include <gphoto2/gphoto2-port-log.h>
#include <gphoto2/gphoto2-setting.h>
#include <gphoto2/gphoto2-camera.h>
#include <gphoto2/gphoto2-context.h>
#include <gp-params.h>
#include "i18n.h"
}
GPParams gp_params;
#define CR(result) {int r = (result); if (r < 0) return (r);}
NikonCtrl::NikonCtrl()
{
}
void
_get_portinfo_list (GPParams *p) {
int count, result;
GPPortInfoList *list = NULL;
if (p->portinfo_list)
return;
if (gp_port_info_list_new (&list) < GP_OK)
return;
result = gp_port_info_list_load (list);
if (result < 0) {
gp_port_info_list_free (list);
return;
}
count = gp_port_info_list_count (list);
if (count < 0) {
gp_port_info_list_free (list);
return;
}
p->portinfo_list = list;
return;
}
int
action_camera_set_port (GPParams *params, const char *port)
{
int p, r;
GPPortInfo info;
char *path;
char verified_port[1024];
verified_port[sizeof (verified_port) - 1] = '\0';
if (!strchr (port, ':')) {
gp_log (GP_LOG_DEBUG, "main", _("Ports must look like "
"'serial:/dev/ttyS0' or 'usb:', but '%s' is "
"missing a colon so I am going to guess what you "
"mean."), port);
if (!strcmp (port, "usb")) {
strncpy (verified_port, "usb:",
sizeof (verified_port) - 1);
} else if (strncmp (port, "/dev/", 5) == 0) {
strncpy (verified_port, "serial:",
sizeof (verified_port) - 1);