Linux下C语言实现LCD屏幕截图

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"


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/405676.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言中#、##宏定义的用法

一、#的用法 #用于编译器编译过程进行预处理。 1、宏定义 #define ON 1#ifndef _PARA_ #define _PARA_ #enddef#ifdef _PARB_ #define DEFAULT_SIZE 1024 #enddef2、宏开关 #if VAR ... #elif ... #end3、显示设定错误 #error ERROR: Not Define4、设置字节对齐 #pragma pac…

linux 正则表达式 视频教程,30分钟带你玩转正则表达式

定义&#xff1a;正则表达式说白了就是有普通字符、以及特殊字符组成的文子模式。{匹配模式标准}正则表达式将会作为一个模板与所搜索的字符串进行匹配。可以让使用者轻易达到搜寻/删除/取代某些特定字符的处理程序。此外vim、grep、find、awk、sed等命令都支持正则表达式注&am…

React开发(224):ant design label绑定值

<Col span{12}><Form className{form-customer} label"同意退运费"><span style{{ fontSize: 14 }}>&#xffe5;</span><Form.Item style{{ width: 20% }}>{getFieldDecorator(freight)(<InputNumber step{1} precision{2} min{0…

数据采集工具flume

概述 flume是在2011年被首次引入到Cloudera的CDH3分发中&#xff0c;2011年6月&#xff0c;Cloudera将flume项目捐献给Apache基金会。2012年&#xff0c;flume项目从孵化器变成了顶级项目&#xff0c;在孵化的这一年中&#xff0c;开发人员就已经开始基于Star Trek Themed标签对…

电脑SSH登陆树莓派Raspberry的两种方式

采用SSH登陆Raspberry需要提前知道Raspberry的IP&#xff0c;SSH登陆端口为22&#xff0c;这里分享两种基于SSH网络登陆树莓派的方式。 一、利用路由器搭建局域网登陆树莓派 1、用路由器搭建局域网&#xff0c;电脑无线或有线方式连接路由器&#xff0c;树莓派用网线连接路由…

linux命令修改内容怎么回退,linux命令(修改).doc

linux命令(修改)第一组 用户管理类命令1 添加用户useradd [选项] 用户名范例&#xff1a;useradd davidls /home vim /etc/passwd2 修改密码passwd [选项] 用户名范例&#xff1a;useradd davidls /home passwd david(修改密码)3 删除用户userdel [选项] 用户名范例&#xff1a…

使用数据库的压测工具super-smack测试mysql数据库性能

一、下载super-smack下载地址&#xff1a;http://vegan.net/tony/supersmack/源码&#xff1a;http://vegan.net/tony/supersmack/super-smack-1.3.tar.gz二、编译及安装配置编译选项&#xff1a;./configure --prefix/usr/local/super-smack-1.3 --with-mysql --with-smacks-d…

React开发(225):render中返回的值可以定义为一个方法

/*** 商品信息 图片&#xff0c;名称、code展示* param {*} data*/goodInfoVal (data) > {return (<div style{{ display: flex, alignItems: center }}><img style{{ width: 100px, marginRight: 8px }} src{data.productImg} alt"" /><div>&…

Linux sed工具用法

一、sed用法 语法&#xff1a; sed [-nefr] [动作] 作用&#xff1a; 以行为单位的新增/删除/修改/插入/替换等功能&#xff0c;bash脚本中常用。sed功能强大&#xff0c;主要体现在[动作]的指定 选项与参数&#xff1a; -n &#xff1a;只有经过 sed 特殊处理的那一行&…

SourceInsight配置

如图&#xff1a; 1&#xff09; SourceInsight: a) 搜索结果直接替换 b) 配置背景色 c) 显示行号、设置tab键宽度为4个空格以及其他 d) 字体设置 e) 不创建备份文件

安卓客户端测试总结

安装测试1.真机上安装卸载&#xff0c;.第方软件&#xff08;91.豌豆荚等2.手机卡/SD卡&#xff0c;.不同的IOS和安卓版本3.安装过程中取消&#xff0c;空间不足4.安装过程来电&#xff0c;短信&#xff0c;完成后&#xff0c;是否继续5.卸载后是否卸载所安装文件6.是否可以删除…

linux防火墙查看被动模式,Centos7搭建vsftpd及被动模式下的防火墙设置

一、安装vsftpd&#xff1a;yum -y install vsftpd二、 创建用户名useradd zhangsanpasswd 123456useradd lisipasswd 123456在配置文件下设置拒绝匿名访问重启下服务systemctl restart vsftpd.service将lisi添加进黑名单vim /etc/vsftpd/ftpusers黑名单是路径位于/etc/vsftpd/…

Android API 中文(77)——AdapterView.OnItemSelectedListener

前言 本章内容是android.widget.AdapterView.OnItemSelectedListener&#xff0c;版本为Android 2.3 r1&#xff0c;翻译来自"cnmahj"&#xff0c;欢迎大家访问他的博客&#xff1a;http://android.toolib.net/blog/&#xff0c;再次感谢"cnmahj"&#xff…

前端小知识点(1):undefined和null区别

目录 一、奇怪点 二、历史原因 三、具体区别 四、代码演示 五、运行结果 一、奇怪点 有点奇怪的是&#xff0c;JavaScript语言居然有两个表示"无"的值&#xff1a;undefined和null。这是为什么&#xff1f; 二、历史原因 1995年JavaScript诞生时&#xff0c;…

六款主流数据恢复软件(绿色版)下载

From: http://hi.baidu.com/zhaodx/item/406401abe55cfa9e14107377 由于我们误操作或病毒侵害等意外情况发生&#xff0c;难免会删除硬盘上的有用数据或文件&#xff0c;此时请记住&#xff1a;千万不要再往这个硬盘里复制文件或写入新的数据了&#xff0c;哪怕已经清空了回收站…

树莓派UART串口编程--使用wiringPi库-C开发【1-基础应用】

一、串口说明 莓派3B上UART串口位于GPIO的8脚和10脚&#xff0c;分别为GPIO8Tx&#xff0c;GPIO10Rx。在连接外部接口时&#xff0c;需要交换接口&#xff0c;即GPIO8连接到外设的Rx&#xff0c;GPIO10连接到外设的Tx。Rpi3的接口如下&#xff1a; Rpi3B的GPIO8和GPIO10该串口…

linux mint视频,Linux Mint 20.1 beta 发布,新增免费视频播放器

经过六个月的开发&#xff0c;Linux Mint 20.1“ Ulyssa”的 Beta 版于近日发布了。Mint 20.1 是一个长期支持(LTS)版本&#xff0c;基于 Ubuntu 20.04 LTS &#xff0c;将持续维护到 2025 年。该 Beta 版本基本上实装了此前预告的一些新功能&#xff0c;并提供了 Cinnamon、MA…

[OT]我的2010(加班无极限)

在今年的最后几天,做一下总结. 1. 今年跳了两次槽(~!#$%^&*()) 前面俩公司还都做WM开发(这不之前写了不少WM文章),不过最后这个公司,做mmo服务器,所以目前一直在做Linux上面的写代码. 成功从C#转型到C. 2. C#->C的转换,是在第二个公司完成的,他们不用C#写WM程序. 第一个…

前端小知识点(5):JS垃圾回收机制

目录 一、什么是垃圾回收 二.垃圾回收机制原理 三、垃圾回收方法 3.1 引用计数 3.2 标记清除 内存常见内存泄露以及解决方法 4.1 全局变量&#xff1a; 4.2 定时器和回调函数 4.3 闭包 4.4 没有清理DOM元素引用&#xff1a; 一、什么是垃圾回收 垃圾回收是一种自…

linux python pymysql,Python之pymysql的使用

在Python3.x中&#xff0c;可以使用pymysql来MySQL数据库的连接&#xff0c;并实现数据库的各种操作&#xff0c;本次博客主要介绍了pymysql的安装和使用方法。PyMySQL的安装一、.windows上的安装方法&#xff1a;在python3.6中&#xff0c;自带pip3&#xff0c;所以在python3中…