From: http://blog.chinaunix.net/uid-24789420-id-3191806.html

一、概述

最近看到网上有人问怎么用C语言实现屏幕截图,刚好自己也在研究Linux驱动,于是花了半天时间把Linux的FrameBuffer驱动看懂了个七八,接着就动手写了个LCD屏幕截图的应用程序。

一些说明:

1. 板子LCD的分辨率为480x272,像素格式为RGB565。

2. 程序首先获取LCD的一些参数 ,然后将获取到的一帧数据转换为RGB24格式,最后用jpeglib库压缩为jpg格式的图片。

   3. 在嵌入式Linux的板子上测试通过。

二、实现

程序中有注释,不多说,直接上程序:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>
#include <linux/fb.h>
#include <jpeglib.h>
#include <jerror.h>/*RGB565转RGB24函数*@rgb565: 指向存放rgb565数据的起始地址*@rgb24:指向存放rgb24数据的起始地址*@width:屏幕(分辨率)的宽度*@height:屏幕(分辨率)的高度*/
int RGB565_to_RGB24(unsigned char *rgb565, unsigned char *rgb24, int width, int height)
{int i;int whole = width*height;unsigned char r, g, b;unsigned short int *pix565;pix565 = (unsigned short int *)rgb565;for(i = 0;i < whole;i++){    r = ((*pix565)>>11)&0x1f;*rgb24 = (r<<3) | (r>>2);rgb24++;g = ((*pix565)>>5)&0x3f;*rgb24 = (g<<2) | (g>>4);rgb24++;b = (*pix565)&0x1f;*rgb24 = (b<<3) | (b>>2);rgb24++;pix565++;    }return 1;
}/*jpeg压缩函数*@rgb:指向存放rgb24数据的起始地址*@width:屏幕(分辨率)的宽度*@height:屏幕(分辨率)的高度
*/
int jpeg_compress(unsigned char *rgb, int width, int height)
{struct jpeg_compress_struct cinfo;struct jpeg_error_mgr jerr;FILE * outfile;JSAMPROW row_pointer[1];int row_stride;cinfo.err = jpeg_std_error(&jerr);jpeg_create_compress(&cinfo);// 输出文件名为:out.jpgif ((outfile = fopen("out.jpg", "wb")) == NULL){printf("can not open out.jpg\n");return -1;}jpeg_stdio_dest(&cinfo, outfile);cinfo.image_width = width;cinfo.image_height = height;cinfo.input_components = 3;              // 1-灰度图,3-彩色图// 输入数据格式为RGBcinfo.in_color_space = JCS_RGB;          // JCS_GRAYSCALE-灰度图,JCS_RGB-彩色图jpeg_set_defaults(&cinfo);jpeg_set_quality(&cinfo, 80, TRUE);        // 设置压缩质量:80jpeg_start_compress(&cinfo, TRUE);       // 开始压缩过程row_stride = width * 3;                   // row_stride: 每一行的字节数while (cinfo.next_scanline < cinfo.image_height){row_pointer[0] = &rgb[cinfo.next_scanline * row_stride];(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);}jpeg_finish_compress(&cinfo);           // 完成压缩过程fclose(outfile);jpeg_destroy_compress(&cinfo);         // 释放资源return 1;
}int main()
{int fd;struct fb_var_screeninfo fb_var_info;struct fb_fix_screeninfo fb_fix_info;unsigned char *trgb;unsigned char *rgb;int buffer_size;// 打开framebuffer设备fd = open("/dev/fb0", O_RDONLY);if(fd < 0){printf("can not open dev\n");exit(1);}// 获取LCD的可变参数ioctl(fd, FBIOGET_VSCREENINFO, &fb_var_info);// 一个像素多少位    printf("bits_per_pixel: %d\n", fb_var_info.bits_per_pixel);// x分辨率printf("xres: %d\n", fb_var_info.xres);// y分辨率printf("yres: %d\n", fb_var_info.yres);// r分量长度(bit)printf("red_length: %d\n", fb_var_info.red.length);// g分量长度(bit)printf("green_length: %d\n", fb_var_info.green.length);// b分量长度(bit)printf("blue_length: %d\n", fb_var_info.blue.length);// t(透明度)分量长度(bit)printf("transp_length: %d\n", fb_var_info.transp.length);// r分量偏移printf("red_offset: %d\n", fb_var_info.red.offset);// g分量偏移printf("green_offset: %d\n", fb_var_info.green.offset);// b分量偏移printf("blue_offset: %d\n", fb_var_info.blue.offset);// t分量偏移printf("transp_offset: %d\n", fb_var_info.transp.offset);// 获取LCD的固定参数ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix_info);// 一帧大小printf("smem_len: %d\n", fb_fix_info.smem_len);// 一行大小printf("line_length: %d\n", fb_fix_info.line_length);// 一帧大小buffer_size = (fb_var_info.xres * fb_var_info.yres * fb_var_info.bits_per_pixel / 8);trgb = (unsigned char *)malloc(buffer_size);if(trgb == NULL)exit(0);rgb = (unsigned char *)malloc(fb_var_info.xres * fb_var_info.yres * 3);if(rgb == NULL){goto here;}if(read(fd, trgb, buffer_size) < 0)       // 获取一帧数据{printf("read failed!\n");goto read_fail;}// 格式转换RGB565_to_RGB24(trgb, rgb, fb_var_info.xres, fb_var_info.yres);// jpeg压缩if(jpeg_compress(rgb, fb_var_info.xres, fb_var_info.yres) < 0)printf("compress failed!\n");        read_fail:free(rgb);
here:free(trgb);close(fd);return 0;
}

注意:编译时加上" -ljpeg"

Linux下C语言实现LCD屏幕截图相关推荐

  1. Linux 应用程序 嵌汇编,Linux下C语言嵌汇编

    Using Assembly Language in Linux. Intel和AT&T汇编语法差异: 1.前缀: Intel汇编寄存器和立即数无需前缀.后者寄存器前缀为%,立即数前缀为$. ...

  2. linux c语言工具,Linux下C语言编程环境的工具.doc

    Linux下C语言编程环境的工具 Linux下C语言编程环境的工具 Linux下C语言编程环境的工具 要想在Linux下进行C语言编程,首先得搭建好一个编程环境.这里分别说明一下几个非常有用的软件包. ...

  3. Linux下C语言编程-进程的创建

    Linux下C语言编程-进程的创建 作者:hoyt 1.进程的概念 Linux操作系统是面向多用户的.在同一时间可以有许多用户向操作系统发出各种命令.那么操作系统是怎么实现多用户的环境呢?在现代的操作 ...

  4. linux父进程中显示子进程pid,请教linux下c语言函数fork父进程打印子进程的PID

    请教linux下c语言函数fork父进程打印子进程的PID 关注:296  答案:2  信息版本:手机版 解决时间 2019-01-14 04:55 雨不眠的下 2019-01-13 12:23 用于 ...

  5. 利用多线程实现linux下C语言的聊天室程序:

    转载:http://www.360doc.com/content/16/0421/11/478627_552531090.shtml 利用多线程实现linux下C语言的聊天室程序: 客户端代码: th ...

  6. linux+下c语言编程项目,精通UNIX下C语言编程与项目实践

    cc -I  //include 目录 -L //静态库目录?动态也可以 -l //小写L,接静态库名称?动态也可以 -DXXX='"XXFF"' //-D直接定义宏 -c 只编译 ...

  7. GCC编译器简明教程(Linux下C语言开发环境的搭建)

    GCC编译器简明教程(Linux下C语言开发环境的搭建) 市面上常见的Linux都是发行版本,典型的Linux发行版包含了Linux内核.桌面环境(例如GNOME.KDE.Unity等)和各种常用的必 ...

  8. 您知道Linux下C语言编程的一些注意事项吗_教育中国

    您知道Linux下C语言编程的一些注意事项吗_教育中国 云风的 BLOG: 一个 C 接口设计的问题 一个 C 接口设计的问题 C 语言在本质上,参数传递都是值传递.不像 Pascal 和 C++ 可 ...

  9. 半双工通信是指c语言,Linux下C语言实现半双工的UDP通信

    ------------恢复内容开始------------ Linux下C语言实现半双工的UDP通信 1.单向通信:又称为单工通信,即只能有一个方向的通信而没有反方向的交互.无线电广播或有线电广播以 ...

最新文章

  1. iOS UITextView 随键盘弹出界面上移
  2. 人工智能的策略,如果国家优先发展”梦想成真”?
  3. gcc undefined reference to 问题解决方法(使用库)
  4. 单步调试学习NgRx createSelector 工具函数的使用方式
  5. 数学推导题,NTT,快速数论变换,Wannafly-导数卷积
  6. 多线程java_初学Java要注意什么 怎么掌握Java多线程知识
  7. CentOS关闭休眠和屏保模式
  8. 黄轩成为QQ阅读新代言人 变身“队长”号召网友 “组队读书”
  9. C语言学习系列(六)基本语法
  10. 华为云linux用户名,玩转华为云服务器ECS:001 如何登录并创建新用户
  11. 计算机配件详情图解,电脑装机教程,详细教您怎么组装电脑
  12. Linux版MySQL下载教程
  13. opencv+ArcFace人脸识别
  14. Axure RP工具介绍
  15. d va爬黑板animate_复合绝缘子的爬电距离(注电案例1295)
  16. 高动态范围(High-Dynamic Range,简称HDR)
  17. 2020寒假第二周总结
  18. Mobile GMaps - Google Map移动版
  19. 项目管理杂谈-需求无止境
  20. 诸葛亮舌战群儒的技术分析总结

热门文章

  1. UIView的旋转iOS开发
  2. 算法基础系列之三:螺旋形矩阵
  3. 2043. 简易银行系统
  4. leetcode684. 冗余连接(并查集)
  5. wp博客写文章500错误_500多个博客文章教我如何撰写出色的文章
  6. hashtable - hashmap
  7. 请问运行py文件的时候怎么样可以不让那个黑框一闪...
  8. (转)在Eclipse中用TODO标签管理任务(Task)
  9. Some Principles
  10. Sqlite 管理工具收藏