日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發布時間:2023/12/9 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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"


總結

以上是生活随笔為你收集整理的Linux下C语言实现LCD屏幕截图的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。