1 /* compile with gcc -Wall -o canon-capture -lgphoto2 canon-capture.c
2 * This code released into the public domain 21 July 2008
3 *
4 * This program does the equivalent of:
5 * gphoto2 --shell
6 * > set-config capture=1
7 * > capture-image-and-download
8 * compile with gcc -Wall -o canon-capture -lgphoto2 canon-capture.c
9 *
10 * Taken from: http://credentiality2.blogspot.com/2008/07/linux-libgphoto2-image-capture-from.html
11 */
12
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <stdio.h>
18 #include <stdarg.h>
19 #include <string.h>
20 #include <gphoto2/gphoto2.h>
21
22 #include "samples.h"
23
errordumper(GPLogLevel level,const char * domain,const char * str,void * data)24 static void errordumper(GPLogLevel level, const char *domain, const char *str,
25 void *data) {
26 printf("%s (data %p)\n", str,data);
27 }
28
29 /* This seems to have no effect on where images go
30 void set_capturetarget(Camera *canon, GPContext *canoncontext) {
31 int retval;
32 printf("Get root config.\n");
33 CameraWidget *rootconfig; // okay, not really
34 CameraWidget *actualrootconfig;
35
36 retval = gp_camera_get_config(canon, &rootconfig, canoncontext);
37 actualrootconfig = rootconfig;
38 printf(" Retval: %d\n", retval);
39
40 printf("Get main config.\n");
41 CameraWidget *child;
42 retval = gp_widget_get_child_by_name(rootconfig, "main", &child);
43 printf(" Retval: %d\n", retval);
44
45 printf("Get settings config.\n");
46 rootconfig = child;
47 retval = gp_widget_get_child_by_name(rootconfig, "settings", &child);
48 printf(" Retval: %d\n", retval);
49
50 printf("Get capturetarget.\n");
51 rootconfig = child;
52 retval = gp_widget_get_child_by_name(rootconfig, "capturetarget", &child);
53 printf(" Retval: %d\n", retval);
54
55
56 CameraWidget *capture = child;
57
58 const char *widgetinfo;
59 gp_widget_get_name(capture, &widgetinfo);
60 printf("config name: %s\n", widgetinfo );
61
62 const char *widgetlabel;
63 gp_widget_get_label(capture, &widgetlabel);
64 printf("config label: %s\n", widgetlabel);
65
66 int widgetid;
67 gp_widget_get_id(capture, &widgetid);
68 printf("config id: %d\n", widgetid);
69
70 CameraWidgetType widgettype;
71 gp_widget_get_type(capture, &widgettype);
72 printf("config type: %d == %d \n", widgettype, GP_WIDGET_RADIO);
73
74
75 printf("Set value.\n");
76
77 // capture to ram should be 0, although I think the filename also plays into
78 // it
79 int one=1;
80 retval = gp_widget_set_value(capture, &one);
81 printf(" Retval: %d\n", retval);
82
83 printf("Enabling capture to CF.\n");
84 retval = gp_camera_set_config(canon, actualrootconfig, canoncontext);
85 printf(" Retval: %d\n", retval);
86 }
87 */
88
89 #if 0
90 static void
91 capture_to_file(Camera *canon, GPContext *canoncontext, char *fn) {
92 int fd, retval;
93 CameraFile *canonfile;
94 CameraFilePath camera_file_path;
95
96 printf("Capturing.\n");
97
98 retval = gp_camera_capture(canon, GP_CAPTURE_IMAGE, &camera_file_path, canoncontext);
99 printf(" Retval: %d\n", retval);
100
101 printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name);
102
103 fd = open(fn, O_CREAT | O_WRONLY | O_BINARY, 0644);
104 retval = gp_file_new_from_fd(&canonfile, fd);
105 printf(" Retval: %d\n", retval);
106 retval = gp_camera_file_get(canon, camera_file_path.folder, camera_file_path.name,
107 GP_FILE_TYPE_NORMAL, canonfile, canoncontext);
108 printf(" Retval: %d\n", retval);
109
110 printf("Deleting.\n");
111 retval = gp_camera_file_delete(canon, camera_file_path.folder, camera_file_path.name,
112 canoncontext);
113 printf(" Retval: %d\n", retval);
114
115 gp_file_free(canonfile);
116 }
117 #endif
118
119 int
main(int argc,char ** argv)120 main(int argc, char **argv) {
121 Camera *canon;
122 int i, retval;
123 GPContext *canoncontext = sample_create_context();
124
125 gp_log_add_func(GP_LOG_ERROR, errordumper, 0);
126 gp_camera_new(&canon);
127
128 /* When I set GP_LOG_DEBUG instead of GP_LOG_ERROR above, I noticed that the
129 * init function seems to traverse the entire filesystem on the camera. This
130 * is partly why it takes so long.
131 * (Marcus: the ptp2 driver does this by default currently.)
132 */
133 printf("Camera init. Takes about 10 seconds.\n");
134 retval = gp_camera_init(canon, canoncontext);
135 if (retval != GP_OK) {
136 printf(" Retval: %d\n", retval);
137 exit (1);
138 }
139 canon_enable_capture(canon, TRUE, canoncontext);
140 retval = camera_eosviewfinder(canon,canoncontext,1);
141 if (retval != GP_OK) {
142 fprintf(stderr,"camera_eosviewfinder(1): %d\n", retval);
143 exit(1);
144 }
145 /*set_capturetarget(canon, canoncontext);*/
146 printf("Taking 100 previews and saving them to snapshot-XXX.jpg ...\n");
147 for (i=0;i<100;i++) {
148 CameraFile *file;
149 char output_file[32];
150
151 fprintf(stderr,"preview %d\n", i);
152 retval = gp_file_new(&file);
153 if (retval != GP_OK) {
154 fprintf(stderr,"gp_file_new: %d\n", retval);
155 exit(1);
156 }
157
158 /* autofocus every 10 shots */
159 if (i%10 == 9) {
160 camera_auto_focus (canon, canoncontext, 1);
161 /* FIXME: wait a bit and/or poll events ? */
162 camera_auto_focus (canon, canoncontext, 0);
163 } else {
164 camera_manual_focus (canon, (i/10-5)/2, canoncontext);
165 }
166 #if 0 /* testcase for EOS zooming */
167 {
168 char buf[20];
169 if (i<10) set_config_value_string (canon, "eoszoom", "5", canoncontext);
170 sprintf(buf,"%d,%d",(i&0x1f)*64,(i>>5)*64);
171 fprintf(stderr, "%d - %s\n", i, buf);
172 set_config_value_string (canon, "eoszoomposition", buf, canoncontext);
173 }
174 #endif
175 retval = gp_camera_capture_preview(canon, file, canoncontext);
176 if (retval != GP_OK) {
177 fprintf(stderr,"gp_camera_capture_preview(%d): %d\n", i, retval);
178 exit(1);
179 }
180 sprintf(output_file, "snapshot-%03d.jpg", i);
181 retval = gp_file_save(file, output_file);
182 if (retval != GP_OK) {
183 fprintf(stderr,"gp_camera_capture_preview(%d): %d\n", i, retval);
184 exit(1);
185 }
186 gp_file_unref(file);
187 /*
188 sprintf(output_file, "image-%03d.jpg", i);
189 capture_to_file(canon, canoncontext, output_file);
190 */
191 }
192 retval = camera_eosviewfinder(canon,canoncontext,0);
193 if (retval != GP_OK) {
194 fprintf(stderr,"camera_eosviewfinder(0): %d\n", retval);
195 exit(1);
196 }
197
198 sleep(10);
199 gp_camera_exit(canon, canoncontext);
200 return 0;
201 }
202