针对 基于海思开发板的屏幕截图程序(一)作了改进,上篇文章的截图结果不正确的原因是:我公司的开发板上fb0中设置的图片格式为ARGB1555,但是我将它作为RGB565来使用,导致转换出来的图片数据不正确,所以压缩后的图片自然会失真。

关键函数是:ARGB1555_to_RGB24() // 将ARGB1555格式的图像数据转换成RGB24的格式。完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
#include <malloc.h>
#include <linux/fb.h>
#include <jpeglib.h>
#include <jerror.h>
#include <errno.h>extern int errno;/*功能:       获取当前系统时间返回值: 指向时间字符串的开始位置
*/
static const char* getCurTime()                 // 获取当前系统时间
{static char ret[30] = {0};time_t t;struct tm *tp;t = time(NULL);tp = localtime(&t);memset(ret, 0, sizeof(ret));sprintf(ret, "%02d%02d%02d_%02d%02d%02d", tp->tm_year+1900, tp->tm_mon+1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);return ret;
}/*功能:      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;                    // 目标缓冲区是RGB格式, 每个分量占1字节, 所以用ucharunsigned short int *pix565;               // 每像素信息占2字节, 所以用short类型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 0;
}/*功能:          将ARGB1555格式的图片数据转换成RGB24的图片数据返回值:           0argb1555:[in]  源缓冲区地址, 指向存放argb1555数据的起始地址rgb24:   [out]   目标缓冲区地址, 指向存放rgb24数据的起始地址xres:          屏幕分辨率的宽度yres:           屏幕分辨率的高度
*/
int ARGB1555_to_RGB24(unsigned char *argb1555, unsigned char *rgb24, int xres, int yres)
{int i;int whole = xres * yres;unsigned char r, g, b;unsigned short int *pix1555;pix1555 = (unsigned short int *)argb1555;for(i = 0; i < whole; i++){// *pix1555 &= 0x7FFFFF;              // 透明分量置为0r = ((*pix1555) >> 10) & 0x1f;     // 取颜色分量: R*rgb24++ = (r << 3) | (r >> 2);g = ((*pix1555) >> 5) & 0x1f;       // 取分量: G*rgb24++ = (g << 3) | (g >> 2);b = (*pix1555) & 0x1f;              // 取分量: B*rgb24++ = (b << 3) | (b >> 2);pix1555++;if(rgb24[-3] == 0xFF && rgb24[-2] == 0 && rgb24[-1] == 0xFF)   // RGB = 0xFF00FFrgb24[-3] = 0;                                               // 修改RGB = 0x0000FF(将粉红色替换成蓝色)}return 0;
}/*功能:  jpeg压缩函数返回值:    0: 成功, -1: 失败rgb:    指向存放rgb24数据的起始地址width:   屏幕(分辨率)的宽度height:   屏幕(分辨率)的高度
*/
int jpeg_compress(unsigned char *rgb, int width, int height)
{char outfile[100] = {0};struct jpeg_compress_struct cinfo;struct jpeg_error_mgr jerr;FILE * pf = NULL;JSAMPROW row_pointer[1];int row_stride;sprintf(outfile, "snap_%s.jpg", getCurTime());if ((pf = fopen(outfile, "wb")) == NULL){printf("Can not create output file, please check!\n");return -1;}cinfo.err = jpeg_std_error(&jerr);jpeg_create_compress(&cinfo);jpeg_stdio_dest(&cinfo, pf);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(pf);jpeg_destroy_compress(&cinfo);          // 释放资源return 0;
}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));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);         // 将RGB565转换成RGB24格式ARGB1555_to_RGB24(trgb, rgb, fb_var_info.xres, fb_var_info.yres);       // 将ARGB1555转换成RGB24格式if(jpeg_compress(rgb, fb_var_info.xres, fb_var_info.yres) < 0)         // jpeg压缩失败printf("Jpeg compress failed!\n");read_fail:free(rgb);
here:free(trgb);close(fd);return 0;
}

至此,程序运行后得到的图片效果与开发板上所看到的效果完全一样,至少肉眼是分不出差异!

makefile文件如下:

CC=arm-hismall-linux-gcca: a.c$(CC) -o $@ $^ -I/opt/jpeg/include /opt/jpeg/lib/libjpeg.aclean:rm -f *.o a

基于海思开发板的屏幕截图程序(二)相关推荐

  1. 海思linux中编译,基于海思开发环境,交叉编译,安装tslib库

    环境:Ubuntu-18.04 64位 交叉编译器:arm-hisiv600-linux tslib版本:tslib-1.4 一.安装交叉编译器 [注意]本文中使用 Hi3531D 的 V600 编译 ...

  2. 海思开发板海图科技测评,海图海思开发板怎么样

    关于海思开发板海图科技的测评,相关关键字:hi3516,hi3519,hi3531,hi3535,hi3536,hi3559,hi3403 最近网络上关于海图的海思开发板宣传的沸沸扬扬,很多人都想要一 ...

  3. 为什么你们说好的程序在我的海思开发板上就是不行呢,难道真的是人品有问题

    就下面的程序,一个利用libpcap做的抓包程序,一个用raw socket 做的抓包程序 海思开发板 是通过映射过来的,被映射的是宝利通mcu rmx1800,终端目前用的是软终端,硬件终端还在路上 ...

  4. 【华为出品】物联网全栈开发实战营第2期来啦!送海思开发板

    物联网一直在改变我们生活的方方面面.可穿戴设备有助于监控我们的偏好.习惯和健康状况.智能家居设备可提高家居的舒适度.安全性和便利性.城市利用连接的数字设备收集的海量数据(数十亿个)来改善城市规划.制造 ...

  5. 《基于海思35xx nnie引擎进行经典目标检测算法模型推理》视频课程介绍

    前言 沉寂两个月,终于将新的视频课程<<基于海思35xx nnie引擎进行经典目标检测算法模型推理>>(其链接为https://edu.csdn.net/course/deta ...

  6. 海思开发板上添加ftp功能

    海思开发板上添加ftp功能 前言: 本博客是基于海思3520Dv100开发,编译工具链为:arm-hisiv100nptl-linux-gcc 1.下载stupid-ftpd-1.5beta.tar. ...

  7. 四、基于海思芯片:从算法到移植 生成海思wk文件并进行成果展示

    一.基于海思芯片:从算法到移植  darknet框架下训练yolov3 二.基于海思芯片:从算法到移植   darknet框架下yolov3转为caffe框架下 三.基于海思芯片:从算法到移植   c ...

  8. mysql移植海思_live555 交叉编译移植到海思开发板

    1.首先到它的主页下载一个源码包: http://www.live555.com/liveMedia/public/ 我下载的是latest的,具体什么版本还真不清楚 2.放到linux目录下解压: ...

  9. 使用telnet来在线调试海思开发板

    前言 在海思MPP软件开发时,往往会遇到一些莫名奇妙的错误或者运行结果和预想不一致(往往是参数没设对引起的).这时候就需要在程序还在运行时来在线查看调试当前的系统状态.如果按CTRL+C强行退出后再去 ...

最新文章

  1. JavaScript中的递归
  2. 同一局域网内_Pycharm访问服务器
  3. Docker中安装DB2的详细教程和DBVisualize的安装教程
  4. 嫌多(线程/进程)太慢? 嫌Scrapy太麻烦?没事,异步高调走起!——瓜子二手车
  5. win7计算机文件夹打开慢,win7开机很慢怎么办 win7电脑开机慢的优化教程
  6. 策略模式-Java实现
  7. linux内核变更导致的错误及解决方案1
  8. scala学习--难点
  9. 使用 nginx 的 stream模块的TCP 转发实现内网SSH
  10. RDP报表工具:详情式报表
  11. Python贪吃蛇 (完整代码+详细注释+粘贴即食)
  12. KnockOutJS入门
  13. windows局域网共享文件
  14. 如何生成密钥文件Snk .
  15. 职业停滞–早期发现和治疗
  16. widows安装wxPython
  17. html5 移动页面,html5入门到精通,移动设备的html5页面布局
  18. 字符流的相关概念和相关方法的使用、IO异常的处理以及Properties属性集
  19. Qt封包生成exe文件
  20. WordPress柒比贰B2 V2.9.9自媒体主题模板

热门文章

  1. 改变自己------每天进步一点点
  2. 在应用程序级别以外使用注册为 allowDefinition='MachineToApplication' 的节是错误
  3. 每个人都应该使用的Python 3中被忽略的3个功能
  4. leetcode860. 柠檬水找零(贪心)
  5. 微服务 边界服务_遵循这些实用原则以获取精心设计的微服务边界
  6. 周末想找个地方敲代码_观看我们的代码游戏,全周末直播
  7. mongo基本使用方法
  8. 面试小问题——Object中有哪些常用方法?
  9. postgresql的别名要用双引号才可以
  10. python项目构建工具zc.buildout