基于海思开发板的屏幕截图程序(一)

来源:互联网 发布:mac iphoto 导出照片 编辑:程序博客网 时间:2024/04/28 06:49

一直以来从事基于海思开发板的开发,但是每次想到“屏幕截图",真的让人非常惭愧!

参考网上的代码修改了下:

#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>#include <errno.h>extern int errno;/*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;const char *dev = "/dev/fb0";// 打开framebuffer设备fd = open(dev, O_RDONLY);if(fd < 0){printf("fd=%d, error=[%d: %s]\n", fd, errno, strerror(errno));printf("dev=[%s]\n", dev);perror("open");return 1;}// 获取LCD的可变参数ioctl(fd, FBIOGET_VSCREENINFO, &fb_var_info);// 一个像素多少位printf("bits_per_pixel: %d\n", fb_var_info.bits_per_pixel);printf("分辨率: %d x %d\n", fb_var_info.xres, fb_var_info.yres);printf("颜色分量值: (A, R, G, B) = (%d, %d, %d, %d)bits\n", fb_var_info.transp.length, fb_var_info.red.length, fb_var_info.green.length, fb_var_info.blue.length);printf("颜色分量偏移: (A, R, G, B) = (%d, %d, %d, %d)\n", fb_var_info.transp.offset, fb_var_info.red.offset, fb_var_info.green.offset, fb_var_info.blue.offset);// 获取LCD的固定参数ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix_info);// 一帧大小printf("smem_len: %#X\n", fb_fix_info.smem_len);// 一行大小printf("line_length: %#X\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;}

最初编译时遇到的最大问题就是:jpeg库是PC上的,而不是适用于嵌入式下的。所以编译之前的第一步工作就是:下载并安装jpeg库

我下载的链接是:http://www.ijg.org/files/jpegsrc.v9.tar.gz

解压到/mnt/other/jpeg-9目录下,再执行以下shell命令:

export CC=arm-hismall-linux-gcc./configure --host=arm-unknow-linux --prefix=/opt/jpeg --enable-shared --enable-static

接下来进行安装:

makemake install

这样,就安装完成了。为了编译我的程序,我写了个简单的makefile文件:

CC=arm-hismall-linux-gccALL=aTarget: $(ALL)a: a.c$(CC) -o $@ $^ -I/opt/jpeg/include /opt/jpeg/lib/libjpeg.acp $@ /tftpboot/DVR/aclean:rm -f *.o $(ALL)

接着就是编译程序了:make

OK, 程序编译完成,在当前目录下生成可执行文件a,不过这个文件只能在开发板上运行噢!


在开发板上挂载/tftpboot/DVR目录,将里面的a拷贝到开发板上可读写的目录下,接着就可以执行a程序了,执行完成后,会在a所在的目录下生成out.jpg图片,这个就是屏幕截图的结果了!将它移到PC上,就可以通过普通的图片浏览工具来预览了!


但是,最终生成的图片还是有点让人失望--存在明显的失真,等有空再研究估计是函数RGB565_to_RGB24()的问题,抽空再改进下!

原创粉丝点击