libgphoto2 plus1

libgphoto2是一个用于连接和控制数码相机的库,支持自动和手动对焦功能。在特定工作模式下,如P、Tv、Av等,才能触发相机的聚焦动作。采集图片时,可通过capture_to_memory()和capture_to_file()函数,前者将图片保存到内存,后者保存到指定文件。此外,文章还详细介绍了这两个函数的内部工作流程。
摘要由CSDN通过智能技术生成

libgphoto2简介

libgphoto home page中有很详细的介绍。

是什么?

libgphoto2是一个用于连接不同的数码相机的库

不是什么?

  1. libgphoto2不是一个一个GUI应用,它只能通过相机理解的语言操作相机,如果一台相机的“语言”没有被公开并且没有人理解该相机的语句,则libgphoto2无法与这类相机“沟通”——无法操作此类相机。
  2. libgphoto2不提供访问USB大容量存储协议的设备,因为该协议已经很成熟了。
  3. 如果有一些设备被当成可以挂载的SCSI磁盘,这样的相机是无法直接使用libgphoto2操作的,除非能够转化为使用不同的通信协议的设备(如PTP)。——如果我们的数码相机中有存储卡,就会被设备认为是USB大容量存储设备,由此就会有一个通信进程占用相机,libgphoto2就无法控制相机采集图片。除非拔掉存储卡或者杀掉相应的进程。

存在的前端

  1. 命令行工具gphoto2
  2. 官方已经不再维护的GUI工具gtkam

以下为gphoto2的整体的系统结构图
结构

操作1:相机聚焦

关于相机聚焦,libgphoto2提供了两个函数接口:分别是camera_auto_focus()camera_manual_focus()。我在测试这两个函数的时候,正常的事情并没有发生,相反,奇怪的事情发生了——函数运行了,但是聚焦动作没有发生,不知道是不是因为聚焦已经完成了。

============================================================
我现在知道为啥单纯地调用camera_auto_focus()camera_manual_focus()相机没有聚焦动作发生了,请听我细细道来:
camera_auto_focus()camera_manual_focus()函数需要在特定的工作模式下才能触发相机的聚焦动作,比如P,Tv,Av之类的。
camera_auto_focus() 是触发相机自动对焦,在支持的模式下,相机可以触发聚焦操作。
camera_manual_focus() 表示手动对焦,可以通过传入的参数对相机的焦距进行调整。通过实验发现,这个函数并不是一次到位地进行调焦,而是根据传入的参数多次调用,每调用一次就微调一次。因此通过模拟libgphoto2中的手动聚焦逻辑,手动聚焦成功。——如果不是连续地调用该函数,聚焦动作不可见且没效果。

操作2:采集图片

采集图片的函数是我使用最多并且最熟悉的部分,有两个函数接口可以完成该操作:分别是capture_to_memory()capture_to_file()。其中,capture_to_file()是控制数码相机采集一张图片,并且将图片以指定的文件名保存到指定的位置。capture_to_memory()从名字上看是采集一张图片,将图片的内容保存到内存中。

capture_to_file()的源代码:
调用该函数执行的操作:

  1. gp_camera_capture()采集一张图片保存在相机缓冲区;
  2. gp_file_new_from_fd()新建文件描述(符);
  3. gp_camera_file_get()从相机中将文件取出,保存到我们指定的位置;
  4. gp_camera_file_delete()删除相机中的文件;
  5. gp_file_free销毁相机文件对象。
void
capture_to_file(Camera *canon, GPContext *canoncontext, char *fn) {
    int fd, retval;
    CameraFile *canonfile;
    CameraFilePath camera_file_path;
    printf("Capturing.\n");

    /* NOP: This gets overridden in the library to /capt0000.jpg */
    strcpy(camera_file_path.folder, "/");
    strcpy(camera_file_path.name, "foo.jpg");

    retval = gp_camera_capture(canon, GP_CAPTURE_IMAGE, &camera_file_path, canoncontext);//采集一张图片,这张图片被保存在相机上,并且可以通过gp_camera_file_get函数下载
    printf("  Retval: %d\n", retval);

    printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name);

    fd = open(fn, O_CREAT | O_WRONLY | O_BINARY, 0644);
    retval = gp_file_new_from_fd(&canonfile, fd);//这个函数从一个UNIX文件描述器新建一个相机文件对象,这个函数获取这个文件描述器的权限并且在关闭相机文件的时候关闭
    printf("  Retval: %d\n", retval);
    retval = gp_camera_file_get(canon, camera_file_path.folder, camera_file_path.name,
             GP_FILE_TYPE_NORMAL, canonfile, canoncontext);//从相机里取回文件
    printf("  Retval: %d\n", retval);

    printf("Deleting.\n");
    retval = gp_camera_file_delete(canon, camera_file_path.folder, camera_file_path.name,
            canoncontext);//将路径/c里的文件删除
    printf("  Retval: %d\n", retval);

    gp_file_free(canonfile);//简单地销毁相机文件对象
}

函数capture_to_memory()的源代码:

  1. gp_camera_capture()采集一张图片并放在相机中;
  2. gp_file_new()创建一个新的相机文件句柄;
  3. gp_camera_file_get()下载文件到相机句柄中;
  4. gp_file_get_data_and_size()获得文件的指针和大小,文件和大小都可以是空。对于regular CameraFiles,返回的指向数据的指针仍然属于libgphoto2并且其生命周期与该file一样。对于基于CameraFiles类型的filedescriptor或者句柄,返回的数据指针属于caller,并且需要调用free函数以免内存泄露;
  5. gp_camera_file_delete()删除相机中的文件;
  6. 没有销毁相机文件对象,说明这里的句柄与capture_to_file 的略有不同。
void
capture_to_memory(Camera *camera, GPContext *context, const char **ptr, unsigned long int *size) {
    int retval;
    CameraFile *file;
    CameraFilePath camera_file_path;

    printf("Capturing.\n");

    /* NOP: This gets overridden in the library to /capt0000.jpg */
    strcpy(camera_file_path.folder, "/");
    strcpy(camera_file_path.name, "foo.jpg");

    retval = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, context);//相机采集,并保存在相机上
    printf("  Retval: %d\n", retval);

    printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name);

    retval = gp_file_new(&file);//创建一个新的相机文件句柄
    printf("  Retval: %d\n", retval);
    retval = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name,
             GP_FILE_TYPE_NORMAL, file, context);//从相机中将文件下载到相机文件句柄中
    printf("  Retval: %d\n", retval);

    gp_file_get_data_and_size (file, ptr, size);//获得指向数据和文件大小的指针,文件和大小都可以是空。对于regular CameraFiles,返回的指向数据的指针仍然属于libgphoto2并且其生命周期与该file一样。
    //对于基于CameraFiles类型的filedescriptor或者句柄,返回的数据指针属于caller,并且需要调用free函数以免内存泄露。

    printf("Deleting.\n");
    retval = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name,
            context);
    printf("  Retval: %d\n", retval);
    /*gp_file_free(file); */
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值