ToB企服应用市场:ToB评测及商务社交产业平台

标题: 在 LCD 上表现 png 图片-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子 [打印本页]

作者: 罪恶克星    时间: 2024-8-1 07:00
标题: 在 LCD 上表现 png 图片-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子
在 LCD 上表现 png 图片


PNG 简介

无损压缩:PNG 使用 LZ77 派生算法举行无损压缩,确保图像质量不受损,且压缩比高

体积小:通过高压缩比,PNG 文件体积小,恰当网络传输

索引彩色模式:PNG-8 格式采用8位调色板,将RGB图像转换为索引彩色图像,镌汰数据量

优化的网络传输表现:PNG 支持流式浏览,允许图像在未完全下载前表现基本内容,恰当网络通讯

支持透明结果:PNG 提供256级透明度,使图像边缘与配景平滑融合,这是GIF和JPEG不具备的特性

libpng 简介

libpng 是用于处理 PNG 图像的库

功能:支持对 PNG 图像文件举行解码和编码

性子:免费、开源的 C 语言函数库

对比:与 libjpeg 类似

zlib 移植

zlib 简介


下载源码包


编译源码


安装目次下的文件夹先容


移植到开发板


libpng 移植

下载源码包


编译源码


安装目次下的文件夹先容


移植到开发板


libpng 使用阐明

libpng 还包含编码功能,但本文不作先容。libpng 官方提供了详细使用文档


libpng 的数据结构


创建和初始化 png_struct 对象


创建和初始化 png_info 对象


设置错误返回点


static jmp_buf buf;
static void hello(void)
{
printf(“hello world!\n”);
longjmp(buf,1);
printf(“Nice to meet you!\n”);
}
int main(void)
{
if(0 == setjmp(buf)) {
printf(“First return\n”);
hello();
}
else
printf(“Second return\n”);
  1. exit(0);
复制代码
}
  1.                 - 验证
  2.                         -  
  3. - libpng 设置错误返回点
  4.         - 错误处理机制:
复制代码
libpng 库使用 setjmp/longjmp 组合处理错误跳转
  1.         - 错误返回点设置:
复制代码
使用 setjmp() 为 libpng 设置错误返回点
  1.         - 错误处理流程:
复制代码
当 libpng 遇到错误时,默认错误处理函数调用 longjmp() 举行跳转。
需要在代码中设置错误返回点,以便在错误发生时举行处理
  1.                 - /*  设置错误返回点   */
复制代码
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return -1;
}
指定命据源


读取 png 图像数据并解码


读取解码后的数据


结束销毁对象


libpng 应用编程

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <sys/ioctl.h>
  8. #include <string.h>
  9. #include <linux/fb.h>
  10. #include <sys/mman.h>
  11. #include <png.h>
  12. static int width;                       //LCD X分辨率
  13. static int height;                      //LCD Y分辨率
  14. static unsigned short *screen_base = NULL;        //映射后的显存基地址
  15. static unsigned long line_length;       //LCD一行的长度(字节为单位)
  16. static unsigned int bpp;    //像素深度bpp
  17. static int show_png_image(const char *path)
  18. {
  19.     png_structp png_ptr = NULL;
  20.     png_infop info_ptr = NULL;
  21.     FILE *png_file = NULL;
  22.     unsigned short *fb_line_buf = NULL; //行缓冲区:用于存储写入到LCD显存的一行数据
  23.     unsigned int min_h, min_w;
  24.     unsigned int valid_bytes;
  25.     unsigned int image_h, image_w;
  26.     png_bytepp row_pointers = NULL;
  27.     int i, j, k;
  28.     /* 打开png文件 */
  29.     png_file = fopen(path, "r");    //以只读方式打开
  30.     if (NULL == png_file) {
  31.         perror("fopen error");
  32.         return -1;
  33.     }
  34.     /* 分配和初始化png_ptr、info_ptr */
  35.     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  36.     if (!png_ptr) {
  37.         fclose(png_file);
  38.         return -1;
  39.     }
  40.     info_ptr = png_create_info_struct(png_ptr);
  41.     if (!info_ptr) {
  42.         png_destroy_read_struct(&png_ptr, NULL, NULL);
  43.         fclose(png_file);
  44.         return -1;
  45.     }
  46.     /* 设置错误返回点 */
  47.     if (setjmp(png_jmpbuf(png_ptr))) {
  48.         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  49.         fclose(png_file);
  50.         return -1;
  51.     }
  52.     /* 指定数据源 */
  53.     png_init_io(png_ptr, png_file);
  54.     /* 读取png文件 */
  55.     png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_ALPHA, NULL);
  56.     image_h = png_get_image_height(png_ptr, info_ptr);
  57.     image_w = png_get_image_width(png_ptr, info_ptr);
  58.     printf("分辨率: %d*%d\n", image_w, image_h);
  59.     /* 判断是不是RGB888 */
  60.     if ((8 != png_get_bit_depth(png_ptr, info_ptr)) &&
  61.         (PNG_COLOR_TYPE_RGB != png_get_color_type(png_ptr, info_ptr))) {
  62.         printf("Error: Not 8bit depth or not RGB color");
  63.         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  64.         fclose(png_file);
  65.         return -1;
  66.     }
  67.     /* 判断图像和LCD屏那个的分辨率更低 */
  68.     if (image_w > width)
  69.         min_w = width;
  70.     else
  71.         min_w = image_w;
  72.     if (image_h > height)
  73.         min_h = height;
  74.     else
  75.         min_h = image_h;
  76.     valid_bytes = min_w * bpp / 8;
  77.     /* 读取解码后的数据 */
  78.     fb_line_buf = malloc(valid_bytes);
  79.     row_pointers = png_get_rows(png_ptr, info_ptr);//获取数据
  80.     unsigned int temp = min_w * 3;  //RGB888 一个像素3个bit位
  81.     for(i = 0; i < min_h; i++) {
  82.         // RGB888转为RGB565
  83.         for(j = k = 0; j < temp; j += 3, k++)
  84.             fb_line_buf[k] = ((row_pointers[i][j] & 0xF8) << 8) |
  85.                 ((row_pointers[i][j+1] & 0xFC) << 3) |
  86.                 ((row_pointers[i][j+2] & 0xF8) >> 3);
  87.         memcpy(screen_base, fb_line_buf, valid_bytes);//将一行数据刷入显存
  88.         screen_base += width;   //定位到显存下一行
  89.     }
  90.     /* 结束、销毁/释放内存 */
  91.     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  92.     free(fb_line_buf);
  93.     fclose(png_file);
  94.     return 0;
  95. }
  96. int main(int argc, char *argv[])
  97. {
  98.     struct fb_fix_screeninfo fb_fix;
  99.     struct fb_var_screeninfo fb_var;
  100.     unsigned int screen_size;
  101.     int fd;
  102.     /* 传参校验 */
  103.     if (2 != argc) {
  104.         fprintf(stderr, "usage: %s <png_file>\n", argv[0]);
  105.         exit(-1);
  106.     }
  107.     /* 打开framebuffer设备 */
  108.     if (0 > (fd = open("/dev/fb0", O_RDWR))) {
  109.         perror("open error");
  110.         exit(EXIT_FAILURE);
  111.     }
  112.     /* 获取参数信息 */
  113.     ioctl(fd, FBIOGET_VSCREENINFO, &fb_var);
  114.     ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix);
  115.     line_length = fb_fix.line_length;
  116.     bpp = fb_var.bits_per_pixel;
  117.     screen_size = line_length * fb_var.yres;
  118.     width = fb_var.xres;
  119.     height = fb_var.yres;
  120.     /* 将显示缓冲区映射到进程地址空间 */
  121.     screen_base = mmap(NULL, screen_size, PROT_WRITE, MAP_SHARED, fd, 0);
  122.     if (MAP_FAILED == (void *)screen_base) {
  123.         perror("mmap error");
  124.         close(fd);
  125.         exit(EXIT_FAILURE);
  126.     }
  127.     /* 显示BMP图片 */
  128.     memset(screen_base, 0xFF, screen_size);//屏幕刷白
  129.     show_png_image(argv[1]);
  130.     /* 退出 */
  131.     munmap(screen_base, screen_size);  //取消映射
  132.     close(fd);  //关闭文件
  133.     exit(EXIT_SUCCESS);    //退出进程
  134. }
复制代码
编写流程和上面先容的libpng 使用阐明一致


编译代码


实验测试



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4