嵌入式Linux截图工具gsnap移植与分析【转】
转自:http://blog.csdn.net/lu_embedded/article/details/53934184
版权声明:开心源自分享,快乐源于生活 —— 分享技术,传递快乐。转载文章请注明出处,谢谢! http://blog.csdn.net/lu_embedded/article/details/53934184
由于 Linux 系统的 FrameBuffer 机制,把屏幕上的每个点映射成一段线性内存空间,这样,程序就可以通过改变这段内存的值来改变屏幕上某一点的颜色。如果我们想把当前的显示内容保存起来,可能会想到如下命令:
# cat /dev/fb0 > fb_data.raw
- 1
反过来,可以将这些数据回显到 framebuffer 中:
# cat fb_data.raw > /dev/fb0
- 1
使用 clear
命令清除,可以恢复正常。
但是,用这用方法保存起来的数据是原始数据,只有专用软件才能打开,并且大小固定(如:8MB)。基于这些原因,我们找到一个不错的工具——gsnap,这个工具可以将 framebuffer 的数据保存为图片(png或jpeg格式)。下面我们介绍一下移植过程。
这里的移植很简单,因为源文件只有 gsnap.c,因此我们只需用相应平台的编译工具链进行编译链接即可。命令如下:
# $(CC) gsnap.c -ljpeg -lpng -o gsnap
- 1
显然,gsnap 需要用到 libjpeg 和 libpng 两个库。那么编译成功与否就跟这两个库有关了。如果你的目标平台还没有这些依赖库,那么就有必要下载相关源码进行编译安装,步骤遵循 configure、make、make install 三部曲。
由于我的目标平台已经包含 libjpeg 和 libpng,于是我尝试用上述命令进行编译,提示缺少头文件,所以编译不成功。然后我将 libjpeg 和 libpng 源码包中的头文件抽取出来,添加到 /usr/include。发现仍然缺少头文件,如下:
- libpng 方面——找不到 pnglibconf.h,经检查发现将 scripts/pnglibconf.h.prebuilt 另存为
pnglibconf.h,并添加到 /usr/include 即可。 - libjpeg 方面——找不到 jconfig.h,经检查发现将 jconfig.txt 另存为 jconfig.h,并添加到
/usr/include 即可。
不用担心,如果你遵循三部曲来安装这些库,上面的 pnglibconf.h 和 jconfig.h 都会在编译的过程中生成。
一旦编译成功,我们就可以运行 gsnap 来截取屏幕画面了。gsnap 的使用也很简单,格式为:
gsnap <jpeg|png file> <framebuffer dev>
- 1
例如:
# ./gsnap test.png /dev/fb0
- 1
我这里用的是 i.mx6q 的 yocto 1.5.3 系统,截图 test.png 如下:
以下是 gsnap.c 的源代码:
/** 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**/#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; } int main(int argc, char* argv[]) { FBInfo fb; const char* filename = NULL; const char* fbfilename = NULL; if(argc != 3) { printf("\nUsage: %s [jpeg|png file] [framebuffer dev]\n", argv[0]); printf("Example: %s fb.jpg /dev/fb0\n", argv[0]); printf("-----------------------------------------\n"); printf("Powered by broncho(www.broncho.cn)\n\n"); return 0; } filename = argv[1]; fbfilename = argv[2]; 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); } return 0; }
嵌入式Linux截图工具gsnap移植与分析【转】相关推荐
- 嵌入式截屏工具-gsnap移植 arm平台
目录 前言 正文 原理 环境 详细流程 使用 参考 前言 由于工作的需要,需要交叉编译一个嵌入式截屏工具,通过网上的查询,用的比较多的就是gsnap.网上也有比较多的资料,参考里的资料基本就是我参考的 ...
- 嵌入式linux usb wifi驱动移植
文档名称:嵌入式linux usb wifi驱动移植 版本历史 版本号 时间 内容 v1.0b001 2012-6-18 初始版本,介绍在嵌入式 ...
- 嵌入式 Linux 开发工具篇问题整理//C语言测试(杨辉三角、递归调用实现阶乘、计算器、统计字符串出现次数)//2018.07.12.//
嵌入式 Linux 开发工具篇问题整理 1. 嵌入式开发与传统开发的区别?(同类问题:单片机开发与嵌入式开发的区别) 是否有无操作系统: 2. 移植操作系统的好处有哪些 ...
- ARM在嵌入式linux内核裁剪与移植的应用
微处理器用一片或少数几片大规模集成电路组成的中央处理器.这些电路执行控制部件和算术逻辑部件的功能.微处理器与传统的中央处理器相比,具有体积小,重量轻和容易模块化等优点.微处理器的基本组成部分有:寄存器 ...
- Linux截图工具import使用说明
1 import 001.jpg 然后可以使用鼠标选择的范围 2 sleep 5; import 001.jpg 等待5秒钟后,截取鼠标选择的范围 3 import -frame 001.jpg 截取 ...
- Mx Linux 截图工具-shutter
SourceURL:file:///home/zttz/文档/WPS Cloud Files/741571795/Mx Linux 截图工具.docx Mx Linux 截图工具-shutter 在M ...
- linux根文件系统的移植 课程设计,定稿基基于ARM9嵌入式Linux引导程序研究与移植嵌入式综合实验报告完整版...
<基<基于ARM9嵌入式Linux引导程序研究与移植>嵌入式综合实验报告.doc>由会员分享,可免费在线阅读全文,更多与<(定稿)基基于ARM9嵌入式Linux引导程序研 ...
- 【嵌入式Linux应用】初步移植MQTT到Ubuntu和Linux开发板
1. 概述 本篇主要是记录将MQTT移植安装到百问网STM32MP157开发板上,并且是跑一下MQTT的一个例程来验证,要完成本次移植安装,必须要保证电脑和开发板都能上网.. 2. 软件平台 ...
- SAIL-IMX7D开发板截屏工具gsnap移植
PC机:ubuntu 14.04.5 开发板:SAIL-IMX7D 交叉编译器:arm-linux-gnueabihf-gcc PC机操作目录:/opt/work/tools/gsnap.没有自行新建 ...
- linux裁剪内核和移植,嵌入式Linux内核裁剪及移植的研究与实现
摘要: 嵌入式操作系统是嵌入式系统的软件核心,它管理系统中所有的软件和硬件资源,并且满足嵌入式系统的专用性和可裁剪性.嵌入式Linux以其开源,可裁剪以及模块化设计等特点,吸引了国内外众多研发人员的青 ...
最新文章
- python设置背景音乐_python给视频添加背景音乐并改变音量的具体方法
- varnish 4.0 官方文档翻译12-VCL
- 变更管理、信息系统安全管理、项目风险管理
- springcloud1.5.9+zipkin链路跟踪配置
- 幼儿园计算机知识培训内容,幼儿园教师计算机培训计划
- springMVC分析-2
- 不止代码 洛谷P1006 传纸条(dp)
- CoreAnimation编程指南(九)图层布局
- python日志保存为html文件,用 Python 抓取公号文章保存成 HTML
- 详细解读!Isotropic Remeshing的详细介绍与实现
- js遍历数组和遍历对象的区别
- day6:vcp考试
- 云服务器Tomcat版本升级(Tomcat6升级至Tomcat7和Tomcat8)问题总结
- SEO必备工具之Xenu(绿蜗牛)网站死链接检测
- Yum安装iso光盘中的软件配置
- IM云通信行业步入快车道,融云或将和Twilio一样实现资本上市
- vue修饰符——.lazy
- 七夕送什么蓝牙耳机,经济实惠的蓝牙耳机盘点
- 柯桥西班牙语培训,西班牙语关于篮球的词汇
- 增值翻译系列谈(01)——概念界定和辨析
热门文章
- ios知识整理 (未完成)
- 黑马程序员————java中面向对象的三大特性
- TinyXML中文文档,TinyXPath
- vSphere 4系列之三:vCenter Server 4.0安装
- mysql 最小值对应的其他属性_查询最小值对应的非group by字段
- C++入门系列博客四 const define static关键字
- 用VS2015编译pjsip的工程pjproject-vs14
- CentOS 6系统FreeSwitch和RTMP服务 安装及演示(四)
- Linux 2.6 中的页面回收与反向映射
- python正则表达式面试题,带有utf8问题的python正则表达式