linux 嵌入式linux截屏工具 gsnap 源码简化完善,附带命令行编译
//
/* * File: gsnap.c * Author: Li XianJing <xianjimli@hotmail.com> * Brief: snap the linux mobile device screen. * * Copyright (c) 2009 Li XianJing <xianjimli@hotmail.com> * * Licensed under the Academic Free License version 2.1 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * History: * ================================================================ * 2009-08-20 Li XianJing <xianjimli@hotmail.com> created * 2011-02-28 Li XianJing <xianjimli@hotmail.com> suppport RGB888 framebuffer. * 2011-04-09 Li XianJing <xianjimli@hotmail.com> merge figofuture's png output. * ref: http://blog.chinaunix.net/space.php?uid=15059847&do=blog&cuid=2040565 * */ /* tqt507 rys 2023-07-20 去除对jpg的支持,丰富指令集合,完善help相关信息 aarch64-linux-gnu-gcc -g gsnap.c -o gsnap -I/opt/EmbedSky/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/sysroot/usr/include/ -I/opt/EmbedSky/TQT507/CoreA/longan/kernel/linux-4.9/arch/arm64/include/ -L/opt/EmbedSky/TQT507/CoreA/longan/out/t507/evb/longan/buildroot/target/usr/lib/ -lpng -lz -lm cp ./gsnap /home/book/nfs_rootfs t113 rys 2024-11-04 arm-openwrt-linux-muslgnueabi-gcc -g gsnap.c -o gsnap -L/home/book/tina-d1-h/out/t113-100ask/staging_dir/target/usr/lib -lpng -lz -lm -I/home/book/tina-d1-h/out/t113-100ask/staging_dir/target/usr/include/ 增加配置文件读写,增加配置名字前缀和序号,增加名字时间戳配置 */ // 2024——11——01 添加 ini 操作,用于记录 文件前缀,和文件索引 #include <ctype.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #define SIZE_LINE 10240 //每行最大长度 #define SIZE_FILENAME 256 //文件名最大长度 #define min(x, y) (x <= y) ? x : y typedef enum _ELineType_ { LINE_IDLE, //未处理行 LINE_ERROR, //错误行 LINE_EMPTY, //空白行或注释行 LINE_SECTION, //节定义行 LINE_VALUE //值定义行 } ELineType ; static char gFilename[SIZE_FILENAME]; static char *gBuffer; static int gBuflen; //去除串首尾空格,原串被改写 static char *StrStrip(char *s) { size_t size; char *p1, *p2; size = strlen(s); if (!size) return s; p2 = s + size - 1; while ((p2 >= s) && isspace(*p2)) p2 --; *(p2 + 1) = '\0'; p1 = s; while (*p1 && isspace(*p1)) p1 ++; if (s != p1) memmove(s, p1, p2 - p1 + 2); return s; } //不区分大小写比较字符串 static int StriCmp(const char *s1, const char *s2) { int ch1, ch2; do { ch1 = (unsigned char)*(s1++); if ((ch1 >= 'A') && (ch1 <= 'Z')) ch1 += 0x20; ch2 = (unsigned char)*(s2++); if ((ch2 >= 'A') && (ch2 <= 'Z')) ch2 += 0x20; } while ( ch1 && (ch1 == ch2) ); return(ch1 - ch2); } //取一行 //输入:数据区(指针及长度) //输出:行类型、有效内容串(去首尾空格)、注释首、注释尾、下一行首(行尾与下一行首间为换行符) // 有效内容位置为[buf, rem1) static int GetLine(char *buf, int buflen, char *content, char **rem1, char **rem2, char **nextline) { char *cont1, *cont2; int cntblank, cntCR, cntLF; //连续空格、换行符数量 char isQuot1, isQuot2; //引号 int i; char *p; //首先断行断注释,支持如下换行符:\r、\n、\r\n、\n\r cntblank = 0; cntCR = cntLF = 0; isQuot1 = isQuot2 = 0; cont1 = *rem1 = 0; content[0] = 0; for (i = 0, p = buf; i < buflen; i ++, p ++) { //printf("i:%d %x %c\n",i,*p,*p); if (*p == 0) { p ++; break; } //2个CR或LF,行结束 if (cntCR == 2 || cntLF == 2) { p --; //回溯1 break; } //CR或LF各1个之后任意字符,行结束 if (cntCR + cntLF >= 2) { break; } //CR或LF之后出现其它字符,行结束 if ((cntCR || cntLF) && *p != '\r' && *p != '\n') break; switch (*p) { case '\r': cntCR ++; break; case '\n': cntLF ++; break; case '\'': if (!isQuot2) isQuot1 = 1 - isQuot1; break; case '\"': if (!isQuot1) isQuot2 = 1 - isQuot2; break; case ';': case '#': if (isQuot1 || isQuot2) break; if (*rem1 == NULL) *rem1 = p - cntblank; break; default: if (isspace((unsigned char)*p)) { cntblank ++; } else { cntblank = 0; if ((*rem1 == NULL) && (cont1 == NULL)) cont1 = p; } break; } } //printf("i:%d cntCR:%d cntLF:%d *rem1:%d cntblank:%d\n",i,cntCR,cntLF,*rem1,cntblank); *nextline = p; *rem2 = p - cntCR - cntLF; if (*rem1 == NULL) *rem1 = *rem2; cont2 = *rem1 - cntblank; if (cont1 == NULL) { cont1 = cont2; return LINE_EMPTY; } // i = (int)(cont2 - cont1); i = i-cntCR-cntLF-cntblank; // printf("cntCR:%d cntLF:%d cntblank:%d i:%d\n",cntCR,cntLF,cntblank,i); if (i >= SIZE_LINE) return LINE_ERROR; //内容头尾已无空格 memcpy(content, cont1, i); content[i] = 0; // printf("i:%d content:%s \n",i,content); if (content[0] == '[' && content[i - 1] == ']') return LINE_SECTION; if (strchr(content, '=') != NULL) return LINE_VALUE; return LINE_ERROR; } //取一节section //输入:节名称 //输出:成功与否、节名称首、节名称尾、节内容首、节内容尾(含换行)、下一节首(节尾与下一节首间为空行或注释行) static int FindSection(const char *section, char **sect1, char **sect2, char **cont1, char **cont2, char **nextsect) { int type; char content[SIZE_LINE]; char *rem1, *rem2, *nextline; char *p; char *empty; int uselen = 0; char found = 0; if (gBuffer == NULL) { return 0; } while (gBuflen - uselen > 0) { p = gBuffer + uselen; type = GetLine(p, gBuflen - uselen, content, &rem1, &rem2, &nextline); uselen += (int)(nextline - p); if (LINE_SECTION == type) { if (found || section == NULL) break; //发现另一section content[strlen(content) - 1] = 0; //去尾部] StrStrip(content + 1); //去首尾空格 if (StriCmp(content + 1, section) == 0) { found = 1; *sect1 = p; *sect2 = rem1; *cont1 = nextline; } empty = nextline; } else if (LINE_VALUE == type) { if (!found && section == NULL) { found = 1; *sect1 = p; *sect2 = p; *cont1 = p; } empty = nextline; } } if (!found) return 0; *cont2 = empty; *nextsect = nextline; return 1; } //从一行取键、值 //输入:内容串(将被改写) //输出:键串、值串 static void GetKeyValue(char *content, char **key, char **value) { char *p; p = strchr(content, '='); *p = 0; StrStrip(content); StrStrip(p + 1); *key = content; *value = p + 1; } // pthread_mutex_lock(&state_mutex); // pthread_mutex_unlock(&state_mutex); #include <pthread.h> static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;//互斥锁 //释放ini文件所占资源 void IniFileFree(void) { if (gBuffer != NULL) { free(gBuffer); gBuffer = 0; gBuflen = 0; } pthread_mutex_unlock(&state_mutex); } //加载ini文件至内存 int IniFileLoad(const char *filename) { pthread_mutex_lock(&state_mutex); FILE *file; int len; IniFileFree(); if (strlen(filename) >= sizeof(gFilename)) return 0; strcpy(gFilename, filename); file = fopen(gFilename, "rb"); if (file == NULL) { file = fopen(gFilename, "w+"); if (file != NULL){ fprintf(file, "[%s]\n%s = %s\n", "____INFO_INIT____", "init", "info"); fclose(file); file = fopen(gFilename, "rb"); if (file == NULL) {return 0;} } else{ return 0; } } fseek(file, 0, SEEK_END); len = ftell(file); gBuffer =(char*) malloc(len); if (gBuffer == NULL) { fclose(file); return 0; } fseek(file, 0, SEEK_SET); len = fread(gBuffer, 1, len, file); // printf("%s\n",gBuffer); fclose(file); gBuflen = len; return 1; } //读取值原始串 static int IniGetValue(const char *section, const char *key, char *value, int maxlen, const char *defvalue) { int type; char content[SIZE_LINE]; char *rem1, *rem2, *nextline; char *key0, *value0; char *p; int uselen = 0; char found = 0; int len; if (gBuffer == NULL || key == NULL) { if (value != NULL) value[0] = 0; return 0; } while (gBuflen - uselen > 0) { p = gBuffer + uselen; type = GetLine(p, gBuflen - uselen, content, &rem1, &rem2, &nextline); uselen += (int)(nextline - p); if (LINE_SECTION == type) { if (found || section == NULL) break; //发现另一section content[strlen(content) - 1] = 0; //去尾部] StrStrip(content + 1); //去首尾空格 if (StriCmp(content + 1, section) == 0) { found = 1; } } else if (LINE_VALUE == type) { if (!found && section == NULL) { found = 1; } if (!found) continue; GetKeyValue(content, &key0, &value0); if (StriCmp(key0, key) == 0) { len = strlen(value0); if (len == 0) break; //空值视为无效 if (value != NULL) { len = min(len, maxlen - 1); strncpy(value, value0, len); value[len] = 0; } return 1; } } } //未发现键值取缺省 if (value != NULL) { if (defvalue != NULL) { len = min(strlen(defvalue), maxlen - 1); strncpy(value, defvalue, len); value[len] = 0; } else { value[0] = 0; } } return 0; } //获取字符串,不带引号 int IniGetString(const char *section, const char *key, char *value, int maxlen, const char *defvalue) { int ret; int len; ret = IniGetValue(section, key, value, maxlen, defvalue); if (!ret) return ret; //去首尾空格 len = strlen(value); if (value[0] == '\'' && value[len - 1] == '\'') { value[len - 1] = 0; memmove(value, value + 1, len - 1); } else if (value[0] == '\"' && value[len - 1] == '\"') { value[len - 1] = 0; memmove(value, value + 1, len - 1); } return ret; } //获取整数值 int IniGetInt(const char *section, const char *key, int defvalue) { char valstr[64]; if (IniGetValue(section, key, valstr, sizeof(valstr), NULL)) return (int)strtol(valstr, NULL, 0); return defvalue; } //获取浮点数 // double IniGetDouble(const char *section, const char *key, double defvalue) // { // char valstr[64]; // if (IniGetValue(section, key, valstr, sizeof(valstr), NULL)) // return (int)atof(valstr); // return defvalue; // } //设置字符串:若value为NULL,则删除该key所在行,包括注释 int IniSetString(const char *section, const char *key, const char *value) { FILE *file; char *sect1, *sect2, *cont1, *cont2, *nextsect; char *p; int len, type; char content[SIZE_LINE]; char *key0, *value0; char *rem1, *rem2, *nextline; if (gBuffer == NULL) { return 0; } if (FindSection(section, §1, §2, &cont1, &cont2, &nextsect) == 0) { //未找到节 //value无效则返回 if (value == NULL) return 0; //在文件尾部添加 file = fopen(gFilename, "ab"); if (file == NULL) return 0; fprintf(file, "\n[%s]\n%s = %s\n", section, key, value); fflush(file); fsync(fileno(file)); fclose(file); IniFileLoad(gFilename); return 1; } //找到节,则节内查找key p = cont1; len = (int)(cont2 - cont1); while (len > 0) { type = GetLine(p, len, content, &rem1, &rem2, &nextline); if (LINE_VALUE == type) { GetKeyValue(content, &key0, &value0); if (StriCmp(key0, key) == 0) { //找到key file = fopen(gFilename, "wb"); if (file == NULL) return 0; len = (int)(p - gBuffer); fwrite(gBuffer, 1, len, file); //写入key之前部分 if (value == NULL) { //value无效,删除 len = (int)(nextline - gBuffer); //整行连同注释一并删除 } else { //value有效,改写 fprintf(file, "%s = %s", key, value); len = (int)(rem1 - gBuffer); //保留尾部原注释! } fwrite(gBuffer + len, 1, gBuflen - len, file); //写入key所在行含注释之后部分 fflush(file); fsync(fileno(file)); fclose(file); IniFileLoad(gFilename); return 1; } } len -= (int)(nextline - p); p = nextline; } //未找到key //value无效则返回 if (value == NULL) return 0; //在文件尾部添加 file = fopen(gFilename, "wb"); if (file == NULL) return 0; len = (int)(cont2 - gBuffer); fwrite(gBuffer, 1, len, file); //写入key之前部分 fprintf(file, "%s = %s\n", key, value); fwrite(gBuffer + len, 1, gBuflen - len, file); //写入key之后部分 fflush(file); fsync(fileno(file)); fclose(file); IniFileLoad(gFilename); return 1; } //设置整数值:base取值10、16、8,分别表示10、16、8进制,缺省为10进制 int IniSetInt(const char *section, const char *key, int value, int base) { char valstr[64]; switch (base) { case 16: sprintf(valstr, "0x%x", value); return IniSetString(section, key, valstr); case 8: sprintf(valstr, "0%o", value); return IniSetString(section, key, valstr); default: //10 sprintf(valstr, "%d", value); return IniSetString(section, key, valstr); } } #ifndef _MY_INI_RW_H_ #define _MY_INI_RW_H_ #ifdef __cplusplus extern "C" { #endif //加载ini文件至内存 int IniFileLoad(const char* filename); //释放ini文件所占资源 void IniFileFree(void); //获取字符串,不带引号 int IniGetString(const char* section, const char* key, char* value, int size, const char* defvalue); //获取整数值 int IniGetInt(const char* section, const char* key, int defvalue); //获取浮点数 //double IniGetDouble(const char* section, const char* key, double defvalue); //设置字符串:若value为NULL,则删除该key所在行,包括注释 int IniSetString(const char* section, const char* key, const char* value); //设置整数值:base取值10、16、8,分别表示10、16、8进制,缺省为10进制 int IniSetInt(const char* section, const char* key, int value, int base); #ifdef __cplusplus }; #endif #endif /* cli.ini [file_server] # ### set file_server ip ### ip=192.1.34.2 [cls_server] # set cls_server ip ip = 192.16.33.2 #include <stdio.h> #include "inirw.h" int main( int argc, char **argv ) { IniFileLoad("./cli.ini"); char ip[128] = {0}; if(argc==3){ IniGetString(argv[1], argv[2], ip, 128, "none");printf("%s\n",ip); } else if(argc==4){ IniSetString(argv[1], argv[2], argv[3]);printf("%s %s=%s\n",argv[1],argv[2],argv[3]); } else{ IniGetString("cls_server", "ip", ip, 128, "none");printf("%s\n",ip); IniGetString("file_server", "ip", ip, 128, "none");printf("%s\n",ip); } IniFileFree(); return 0; } */ #include <png.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> //#include <jpeglib.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <linux/fb.h> #include <linux/kd.h> struct _FBInfo; typedef struct _FBInfo FBInfo; typedef int (*UnpackPixel)(FBInfo* fb, unsigned char* pixel, unsigned char* r, unsigned char* g, unsigned char* b); struct _FBInfo { int fd; UnpackPixel unpack; unsigned char *bits; struct fb_fix_screeninfo fi; struct fb_var_screeninfo vi; }; #define fb_width(fb) ((fb)->vi.xres) #define fb_height(fb) ((fb)->vi.yres) #define fb_bpp(fb) ((fb)->vi.bits_per_pixel>>3) #define fb_size(fb) ((fb)->vi.xres * (fb)->vi.yres * fb_bpp(fb)) static int fb_unpack_rgb565(FBInfo* fb, unsigned char* pixel, unsigned char* r, unsigned char* g, unsigned char* b) { unsigned short color = *(unsigned short*)pixel; *r = ((color >> 11) & 0xff) << 3; *g = ((color >> 5) & 0xff) << 2; *b = (color & 0xff )<< 3; return 0; } static int fb_unpack_rgb24(FBInfo* fb, unsigned char* pixel, unsigned char* r, unsigned char* g, unsigned char* b) { *r = pixel[fb->vi.red.offset>>3]; *g = pixel[fb->vi.green.offset>>3]; *b = pixel[fb->vi.blue.offset>>3]; return 0; } static int fb_unpack_argb32(FBInfo* fb, unsigned char* pixel, unsigned char* r, unsigned char* g, unsigned char* b) { *r = pixel[fb->vi.red.offset>>3]; *g = pixel[fb->vi.green.offset>>3]; *b = pixel[fb->vi.blue.offset>>3]; return 0; } static int fb_unpack_none(FBInfo* fb, unsigned char* pixel, unsigned char* r, unsigned char* g, unsigned char* b) { *r = *g = *b = 0; return 0; } static void set_pixel_unpacker(FBInfo* fb) { if(fb_bpp(fb) == 2) { fb->unpack = fb_unpack_rgb565; } else if(fb_bpp(fb) == 3) { fb->unpack = fb_unpack_rgb24; } else if(fb_bpp(fb) == 4) { fb->unpack = fb_unpack_argb32; } else { fb->unpack = fb_unpack_none; printf("%s: not supported format.\n", __func__); } return; } static int fb_open(FBInfo* fb, const char* fbfilename) { fb->fd = open(fbfilename, O_RDWR); if (fb->fd < 0) { fprintf(stderr, "can't open %s\n", fbfilename); return -1; } if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->fi) < 0) goto fail; if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vi) < 0) goto fail; fb->bits = mmap(0, fb_size(fb), PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0); if (fb->bits == MAP_FAILED) goto fail; printf("---------------framebuffer---------------\n"); printf("%s: \n width : %8d\n height: %8d\n bpp : %8d\n r(%2d, %2d)\n g(%2d, %2d)\n b(%2d, %2d)\n", fbfilename, fb_width(fb), fb_height(fb), fb_bpp(fb), fb->vi.red.offset, fb->vi.red.length, fb->vi.green.offset, fb->vi.green.length, fb->vi.blue.offset, fb->vi.blue.length); printf("-----------------------------------------\n"); set_pixel_unpacker(fb); return 0; fail: printf("%s is not a framebuffer.\n", fbfilename); close(fb->fd); return -1; } static void fb_close(FBInfo* fb) { munmap(fb->bits, fb_size(fb)); close(fb->fd); return; } /* static int snap2jpg(const char * filename, int quality, FBInfo* fb) { int row_stride = 0; FILE * outfile = NULL; JSAMPROW row_pointer[1] = {0}; struct jpeg_error_mgr jerr; struct jpeg_compress_struct cinfo; memset(&jerr, 0x00, sizeof(jerr)); memset(&cinfo, 0x00, sizeof(cinfo)); cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); if ((outfile = fopen(filename, "wb+")) == NULL) { fprintf(stderr, "can't open %s\n", filename); return -1; } jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = fb_width(fb); cinfo.image_height = fb_height(fb); cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); jpeg_start_compress(&cinfo, TRUE); row_stride = fb_width(fb) * 2; JSAMPLE* image_buffer = malloc(3 * fb_width(fb)); while (cinfo.next_scanline < cinfo.image_height) { int i = 0; int offset = 0; unsigned char* line = fb->bits + cinfo.next_scanline * fb_width(fb) * fb_bpp(fb); for(i = 0; i < fb_width(fb); i++, offset += 3, line += fb_bpp(fb)) { fb->unpack(fb, line, image_buffer+offset, image_buffer + offset + 1, image_buffer + offset + 2); } row_pointer[0] = image_buffer; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); return 0; } */ //Ref: http://blog.chinaunix.net/space.php?uid=15059847&do=blog&cuid=2040565 static int snap2png(const char * filename, int quality, FBInfo* fb) { FILE *outfile; if ((outfile = fopen(filename, "wb+")) == NULL) { fprintf(stderr, "can't open %s\n", filename); return -1; } /* prepare the standard PNG structures */ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); png_infop info_ptr = png_create_info_struct(png_ptr); /* setjmp() must be called in every function that calls a PNG-reading libpng function */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(outfile); return -1; } /* initialize the png structure */ png_init_io(png_ptr, outfile); // int width = 0; int height = 0; int bit_depth = 8; int color_type = PNG_COLOR_TYPE_RGB; int interlace = 0; width = fb_width(fb); height = fb_height(fb); png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type, (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* write the file header information */ png_write_info(png_ptr, info_ptr); png_bytep row_pointers[height]; png_byte* image_buffer = malloc(3 * width); int i = 0; int j = 0; unsigned char* line = NULL; for( ; i < height; i++ ) { line = (char*)fb->bits + i * width * fb_bpp(fb); for(j = 0; j < width; j++, line += fb_bpp(fb)) { int offset = j * 3; fb->unpack(fb, line, image_buffer+offset, image_buffer+offset+1, image_buffer+offset+2); } row_pointers[i] = image_buffer; png_write_rows(png_ptr, &row_pointers[i], 1); } png_destroy_write_struct(&png_ptr, &info_ptr); fclose(outfile); return 0; } void FuncHelp__rys(char* argv[]){ printf("-----------------help------------------------\n\n"); printf("Usage: %s [png file] [framebuffer dev]\n", argv[0]); printf("Usage: %s [framebuffer dev] [png file]\n", argv[0]); printf("Usage: %s set subname [gsnap]\n", argv[0]); printf("Usage: %s set subname [gsnap] [0]\n", argv[0]); printf("Usage: %s set subindex [0]\n", argv[0]); printf("Usage: %s set timestamp [on/off]\n", argv[0]); printf("Example: %s set subname gsnap\n", argv[0]); printf("Example: %s set subname gsnap 0\n", argv[0]); printf("Example: %s set subindex 1\n", argv[0]); printf("Example: %s set timestamp on\n", argv[0]); printf("Example: %s set timestamp off\n", argv[0]); printf("Example: %s fb.png /dev/fb0\n", argv[0]); printf("Example: %s /dev/fb0 fb.png\n", argv[0]); printf("Example: %s fb.png\n", argv[0]); printf("Example: %s /dev/fb0\n", argv[0]); printf("Example: %s\n", argv[0]); printf("Attention: default framebuffer -> /dev/fb0\n"); printf("\n-----------------help------------------------\n"); exit(0); } #include <sys/time.h> #include <string.h> int main(int argc, char* argv[]) { FBInfo fb; const char* filename = NULL; const char* fbfilename = NULL; //time_t current_time; time(¤t_time); //char* time_string = ctime(¤t_time); struct timeval current_time; gettimeofday(¤t_time, NULL); char _filename[128]; char _subname[64]={0}; int timestamp=1;//1 有效 0 无效 IniFileLoad(".config_gsnap.ini"); IniGetString("sub", "timestamp", _subname, sizeof(_subname), "off"); if(strcmp(_subname, "off")==0){timestamp=0;} IniGetString("sub", "subname", _subname, sizeof(_subname), "gsnap"); int _subindex=IniGetInt("sub", "subindex",0); IniSetInt("sub", "subindex",_subindex+1,10); IniFileFree(); if(timestamp==1){ char time_string[100]; struct tm* timeinfo; timeinfo = localtime(¤t_time.tv_sec); strftime(time_string, sizeof(time_string), "%Y_%m_%d__%H_%M_%S", timeinfo); sprintf(time_string + strlen(time_string), "__%03ld", current_time.tv_usec / 1000); sprintf(_filename,"%s_%03d__%s.png",_subname,_subindex,time_string); } else {sprintf(_filename,"%s_%03d.png",_subname,_subindex);} fbfilename="/dev/fb0"; filename=_filename; if(argc==1){ } else if(argc==2){ if(strstr(argv[1], ".png") != NULL){ filename = argv[1]; } else if(strstr(argv[1], "-h") != NULL){ FuncHelp__rys(argv); } else if(strstr(argv[1], "/dev") != NULL) { fbfilename = argv[1]; } else { FuncHelp__rys(argv); } } else if(argc==3){ if(strstr(argv[1], ".png") != NULL && strstr(argv[2], "/dev") != NULL){ filename = argv[1]; fbfilename = argv[2]; } else if(strstr(argv[1], "/dev") != NULL && strstr(argv[2], ".png") != NULL) { filename = argv[2]; fbfilename = argv[1]; } else{ FuncHelp__rys(argv); } } else if(argc>=4 && strcmp(argv[1], "set")==0){ if(strstr(argv[2], "subname") != NULL){ IniFileLoad(".config_gsnap.ini"); IniSetString("sub", "subname", argv[3]); int _subindex=0; if(argc==5){ _subindex=atoi(argv[4]); if(_subindex<0){_subindex=0;} } IniSetInt("sub", "subindex",_subindex,10); IniFileFree(); printf("%s set ok subname !!!\n",argv[0]); } else if(strstr(argv[2], "subindex") != NULL){ IniFileLoad(".config_gsnap.ini"); int _subindex=0; if(argc==5){ _subindex=atoi(argv[3]); if(_subindex<0){_subindex=0;} } IniSetInt("sub", "subindex",_subindex,10); IniFileFree(); printf("%s set ok subindex !!!\n",argv[0]); } else if(strstr(argv[2], "timestamp") != NULL){ IniFileLoad(".config_gsnap.ini"); IniSetString("sub", "timestamp", argv[3]); IniFileFree(); printf("%s set ok timestamp !!!\n",argv[0]); } else{ FuncHelp__rys(argv); } exit(0); // FuncHelp__rys(argv); } else { FuncHelp__rys(argv); } printf("%s doing !!!\n",filename); memset(&fb, 0x00, sizeof(fb)); if (fb_open(&fb, fbfilename) == 0) { if(strstr(filename, ".png") != NULL) { snap2png(filename, 100, &fb); } else { //snap2jpg(filename, 100, &fb); } fb_close(&fb); } printf("%s finished !!!\n",filename); return 0; }
//
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?