IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux LVGL Framebuffer截屏保存为PNG图片 -> 正文阅读

[系统运维]Linux LVGL Framebuffer截屏保存为PNG图片

Framebuffer截屏保存为PNG图片

产品做说明书,或开发过程中有时的沟通,常有截屏的需求!一般的UI开发库中也有这个基本的功能,截屏功能!
其实比较简单,把FrameBuffer中的内存拷出来,写到PNG图片即可!

调试时,把RGB的顺序搞反了,保存的图片,色彩总是不对,见下面代码的for代码,libpng中有一个接口设置RGB顺序了: png_set_bgr 。
在不同的平台获取的数据可能不同,需要根据实际情况调整! 这里UI也是32位的RGBA,Framebuffer也是设置成为32的RGBA方式!

开发中如果色彩不对,可以在UI里设置一个区域的颜色的R,G,B值都写好,在下面的拷贝内存中这个位置的RGB值分别打印现来,应该就很快定位问题!

PUPANVR这个工程里,添加了 view/TViewScreenSnap.h里实现了这个功能!
代码位置: https://gitee.com/jhting/pupanvr/blob/develop/app/appmain/view/TViewScreenSnap.cpp
代码是在LVGL的UI中做的,在fbdev.c中改了一下几个函数!

	void fbdev_get_sizes(uint32_t *width, uint32_t *height, uint32_t *line_length);	
	char* fbdev_get_framebufferMapAddr();

上面只是改了一下 fbdev_get_sizes, 添加了 fbdev_get_framebufferMapAddr 获取打开的地址!这样不用再去open一个framebuffer设备了!

截屏代码实现如下:

	
bool TViewScreenSnap::screenSnap(const char* pngFileName)
{
    unsigned int width = 0;
    unsigned int height = 0;
    unsigned int line_length = 0;
    unsigned int bit_depth = 8;

    unsigned int i = 0;
    unsigned int k = 0;
    unsigned char *rawDataBuffer = NULL;

    FILE *fp = NULL;

    char* framebufferDevAddr = fbdev_get_framebufferMapAddr();
    if(!framebufferDevAddr)
    {
        return false;
    }

    fbdev_get_sizes(&width, &height, &line_length);

    if(width == 0 || height == 0 || line_length == 0)
    {
        return false;
    }

    png_structp png_ptr;
    png_infop info_ptr;

    fp = fopen(pngFileName, "wb");
    if(!fp)
    {
        printf("screenSnap open file %s failure!\n", pngFileName);
        return false;
    }

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    if (png_ptr == NULL)
    {
        printf("png_create_write_struct failure!\n");
        fclose(fp);
        return false;
    }

    rawDataBuffer = (unsigned char*)malloc(line_length);
    if(!rawDataBuffer)
    {
        fclose(fp);
        png_destroy_write_struct(&png_ptr,  NULL);
        return false;
    }

     /* Allocate/initialize the image information data.  REQUIRED */
    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL)
    {
        fclose(fp);
        free(rawDataBuffer);
        png_destroy_write_struct(&png_ptr,  NULL);
        return false;
    }

       /* Set error handling.  REQUIRED if you aren't supplying your own
    * error handling functions in the png_create_write_struct() call.
    */
   if (setjmp(png_jmpbuf(png_ptr)))
   {
      /* If we get here, we had a problem writing the file */
      fclose(fp);
      free(rawDataBuffer);
      png_destroy_write_struct(&png_ptr, &info_ptr);
      return false;
   }

    //png_set_swap_alpha(png_ptr);

    png_init_io(png_ptr, fp);
  
    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_RGBA,
       PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    
    png_set_packing(png_ptr);

    //frame BGRA      ->   RGBA
    png_set_bgr(png_ptr);

    png_write_info(png_ptr, info_ptr);

    unsigned char* pRawRowData = (unsigned char*)framebufferDevAddr;
	for(k = 0; k < height; k++) 
    {
        #if 1
            memcpy(rawDataBuffer, framebufferDevAddr + k * line_length, line_length);
        #else
            pRawRowData = (unsigned char*)(framebufferDevAddr + k * line_length);
            for(i = 0; i < line_length; i = i + 4)
            {  
                //frame BGRA      ->   RGBA
                rawDataBuffer[i + 0] = pRawRowData[i + 2];     //R              
                rawDataBuffer[i + 1] = pRawRowData[i + 1];     //G
                rawDataBuffer[i + 2] = pRawRowData[i + 0];     //B
                rawDataBuffer[i + 3] = pRawRowData[i + 3];     //A
            }
        
        #endif
		png_write_row(png_ptr, rawDataBuffer);
	}

    png_write_end(png_ptr, info_ptr);
    png_destroy_write_struct(&png_ptr, &info_ptr);

    free(rawDataBuffer);
    fclose(fp);
    return true;
}

效果图!
在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 16:03:51  更:2022-02-28 16:04:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 4:47:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码