📄 .#webcam.c.1.19
字号:
/* * (c) 1998-2000 Gerd Knorr * * capture a image, compress as jpeg and upload to the webserver * q * using ftp the ftp utility * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <stdarg.h>#include <errno.h>#include <fcntl.h>#include <sys/time.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <X11/Xlib.h>#include <Imlib2.h>#include <giblib.h>#include <curl/types.h>#include <curl/curl.h>#include <curl/easy.h>#include <asm/types.h>#include "videodev.h"#include "parseconfig.h"void log(char *fmt, ...);char *ftp_host = "www";char *ftp_user = "webcam";char *ftp_pass = "xxxxxx";char *ftp_dir = "public_html/images";char *ftp_file = "webcam.jpeg";char *ftp_tmp = "uploading.jpeg";int ftp_debug = 0;char *temp_file = "/tmp/webcam.jpg";int ftp_passive = 1;int ftp_do = 1;char *scp_target = NULL;char *grab_device = "/dev/video0";char *grab_text = "webcam %Y-%m-%d %H:%M:%S"; /* strftime */char *action_pre_shot = NULL;char *action_post_shot = NULL;char *action_post_upload = NULL;char *grab_infofile = NULL;char *logfile = NULL;int grab_width = 320;int grab_height = 240;int grab_delay = 3;int grab_quality = 75;int lag_reduce = 5;int text_r = 255;int text_g = 255;int text_b = 255;int text_a = 255;char *text_font = "arial/8";int title_r = 255;int title_g = 255;int title_b = 255;int title_a = 255;int bg_r = 0;int bg_g = 0;int bg_b = 0;int bg_a = 150;int close_dev = 0;int ftp_timeout = 30;char *title_font = "arial/8";char *ttf_dir = "/usr/X11R6/lib/X11/fonts/TrueType";char *grab_archive = NULL;char *grab_blockfile = NULL;char *upload_blockfile = NULL;char *grab_postprocess = NULL;char *title_text = NULL;gib_style *title_style = NULL;gib_style *text_style = NULL;char *title_style_file = NULL;char *text_style_file = NULL;char *overlay_file = NULL;Imlib_Image overlay_im = NULL;int overlay_x = 0, overlay_y = 0;Imlib_Font title_fn, text_fn;int v_width[5] = { 128, 160, 176, 320, 640 };int v_height[5] = { 96, 120, 144, 240, 480 };int v_curr = -1;int v_force = 0;int bw_percent = 100;int delay_correct = 0;int reinit_device = 0;/* these work for v4l only, not v4l2 */int grab_input = 0;int grab_norm = VIDEO_MODE_PAL;static struct video_mmap grab_buf;static int grab_fd = -1;static int grab_size = 0;static unsigned char *grab_data = NULL;Imlib_Image convert_rgb_to_imlib2(unsigned char *mem, int width, int height);voidclose_device(){ if (munmap(grab_data, grab_size) != 0) { perror("munmap()"); exit(1); } grab_data = NULL; if (close(grab_fd)) perror("close(grab_fd) "); grab_fd = -1;}voidgrab_init(){ struct video_capability grab_cap; struct video_channel grab_chan; struct video_mbuf vid_mbuf; if ((grab_fd = open(grab_device, O_RDWR)) == -1) { fprintf(stderr, "open %s: %s\n", grab_device, strerror(errno)); exit(1); } if (ioctl(grab_fd, VIDIOCGCAP, &grab_cap) == -1) { fprintf(stderr, "%s: no v4l device\n", grab_device); exit(1); } /* set image source and TV norm */ grab_chan.channel = grab_input; if (ioctl(grab_fd, VIDIOCGCHAN, &grab_chan) == -1) { perror("ioctl VIDIOCGCHAN"); exit(1); } grab_chan.channel = grab_input; grab_chan.norm = grab_norm; if (ioctl(grab_fd, VIDIOCSCHAN, &grab_chan) == -1) { perror("ioctl VIDIOCSCHAN"); exit(1); } /* try to setup mmap-based capture */ grab_buf.format = VIDEO_PALETTE_RGB24; grab_buf.frame = 0; grab_buf.width = grab_width; grab_buf.height = grab_height; ioctl(grab_fd, VIDIOCGMBUF, &vid_mbuf); /* grab_size = grab_buf.width * grab_buf.height * 3; */ grab_size = vid_mbuf.size; grab_data = mmap(0, grab_size, PROT_READ | PROT_WRITE, MAP_SHARED, grab_fd, 0); if ((grab_data == NULL) || (-1 == (int) grab_data)) { fprintf(stderr, "couldn't mmap vidcam. your card doesn't support that?\n"); exit(1); }}Imlib_Imagegrab_one(int *width, int *height){ Imlib_Image im; int i = 0; int j = lag_reduce; if (j == 0) j++; while (j--) { if (grab_fd == -1) grab_init(); if (ioctl(grab_fd, VIDIOCMCAPTURE, &grab_buf) == -1) { perror("ioctl VIDIOCMCAPTURE"); return NULL; } if (ioctl(grab_fd, VIDIOCSYNC, &i) == -1) { perror("ioctl VIDIOCSYNC"); return NULL; } } im = convert_rgb_to_imlib2(grab_data, grab_buf.width, grab_buf.height); if (close_dev) close_device(); if (im) { imlib_context_set_image(im); imlib_image_attach_data_value("quality", NULL, grab_quality, NULL); } *width = grab_buf.width; *height = grab_buf.height; return im;}char *get_message(void){ static char buffer[4096]; FILE *fp; fp = fopen(grab_infofile, "r"); if (fp) { fgets(buffer, sizeof(buffer), fp); fclose(fp); return buffer; } return NULL;}/* ---------------------------------------------------------------------- */voidadd_time_text(Imlib_Image image, char *message, int width, int height){ time_t t; struct tm *tm; char line[255], title_line[255]; int len; int x, y, w, h; time(&t); tm = localtime(&t); strftime(line, 254, grab_text, tm); if (title_text) strftime(title_line, 254, title_text, tm); if (message) strcat(line, message); line[127] = '\0'; len = strlen(line); if (line[len - 1] == '\n') line[--len] = '\0'; if (title_text && title_fn) { gib_imlib_get_text_size(title_fn, title_line, title_style, &w, &h, IMLIB_TEXT_TO_RIGHT); x = width - w - 2; y = 2; gib_imlib_image_fill_rectangle(image, x - 2, y - 1, w + 4, h + 2, bg_r, bg_g, bg_b, bg_a); gib_imlib_text_draw(image, title_fn, title_style, x, y, title_line, IMLIB_TEXT_TO_RIGHT, title_r, title_g, title_b, title_a); } if (line && text_fn) { gib_imlib_get_text_size(text_fn, line, text_style, &w, &h, IMLIB_TEXT_TO_RIGHT); x = 2; y = height - h - 2; gib_imlib_image_fill_rectangle(image, x - 2, y - 1, w + 4, h + 2, bg_r, bg_g, bg_b, bg_a); gib_imlib_text_draw(image, text_fn, text_style, x, y, line, IMLIB_TEXT_TO_RIGHT, text_r, text_g, text_b, text_a); }}Imlib_Imageconvert_rgb_to_imlib2(unsigned char *mem, int width, int height){ Imlib_Image im; DATA32 *data, *dest; unsigned char *src; int i; im = imlib_create_image(width, height); imlib_context_set_image(im); data = imlib_image_get_data(); dest = data; src = mem; i = width * height; while (i--) { *dest = (src[2] << 16) | (src[1] << 8) | src[0] | 0xff000000; dest++; src += 3; } imlib_image_put_back_data(data); return im;}/* ---------------------------------------------------------------------- */voiddo_postprocess(char *filename){ if (grab_postprocess) { char buf[4096]; log("executing postprocessing\n"); snprintf(buf, sizeof(buf), "%s %s", grab_postprocess, filename); system(buf); }}voidarchive_jpeg(Imlib_Image im){ char buffer[1028]; char date[128]; time_t t; struct tm *tm; struct stat st; if (grab_archive) { time(&t); tm = localtime(&t); strftime(date, 127, "%Y-%m-%d_%H%M%S", tm); do { snprintf(buffer, sizeof(buffer), "%s/webcam_%s.jpg", grab_archive, date); } while (stat(buffer, &st) == 0); gib_imlib_save_image(im, buffer); }}voidlog(char *fmt, ...){ va_list args; time_t t; struct tm *tm; char date[128]; FILE *fp; if (!logfile) return; fp = fopen(logfile, "a"); if (!fp) { fprintf(stderr, "can't open log file %s\n", logfile); exit(2); } time(&t); tm = localtime(&t); strftime(date, 127, "%d/%m %H:%M:%S", tm); fprintf(fp, "%s ", date); va_start(args, fmt); vfprintf(fp, fmt, args); va_end(args); fclose(fp);}voiddraw_overlay(Imlib_Image image){ int w, h; w = gib_imlib_image_get_width(overlay_im); h = gib_imlib_image_get_height(overlay_im); gib_imlib_blend_image_onto_image(image, overlay_im, 0, 0, 0, w, h, overlay_x, overlay_y, w, h, 0, gib_imlib_image_has_alpha(overlay_im), 0);};voidbw_res_change(int diff){ int temp = 0; if (!diff) return; if (v_curr == -1) { while (temp < 5) { if (grab_buf.height == v_height[temp]) v_curr = temp; temp++; } if (v_curr == -1) { bw_percent = 100; fprintf(stderr, "You don't appear to be running any of the resolutions\n"); fprintf(stderr, "req'd by the bandwidth limiter. It has been deactivated.\n"); log("method bw_percent killed, not at support'd res\n"); } } if (diff > (grab_delay * bw_percent) / 100) { log("bw_res_change Not enough bandwidth.\n"); if (v_force < -1 && v_curr > 0) { log("bw_res_change Reducing image resolution.\n"); grab_buf.height = v_height[--v_curr]; grab_buf.width = v_width[v_curr]; } v_force--; } else if (diff < (grab_delay * bw_percent) / 200) { if (v_force > 1 && v_curr < 5) { log("bw_res_change Increasing image resolution.\n"); grab_buf.height = v_height[++v_curr]; grab_buf.width = v_width[v_curr]; } v_force++; } else v_force = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -