前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示jpg图片

荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示jpg图片

作者头像
Gnep@97
发布2023-08-10 10:17:53
3850
发布2023-08-10 10:17:53
举报
文章被收录于专栏:Gnep's_Technology_Blog

前言

由于从上篇博文 “荔枝派Zero(全志V3S)驱动开发之RGB LCD屏幕显示bmp图片” 中只实现了显示 bmp 图片,实际上我们很常用到的图片多数是 jpg 格式图片,因此我们需要折腾一下,实现 jpg 文件的显示。

一、jpeglib 库移植

1、jpeglib 库下载

下载网址:http://www.ijg.org/files

在这里插入图片描述
在这里插入图片描述

这里我选择最新的一个版本,即 jpegsrc.v9e.tar.gz 这个 jpeglib 库

2、安装 jpeglib 库

源码的安装一般由3个步骤组成:配置(configure)、编译(make)、安装(make install)。 <1>、创建安装目录 在 Linux PC 机上新建一个文件夹,用于存放安装文件,并将 jpegsrc.v9e.tar.gz 拷贝到当前目录下:

代码语言:javascript
复制
mkdir /home/Gnep/licheepi_zero/tools
cd tools/
cp /home/share/jpegsrc.v9e.tar.gz ./
ls
在这里插入图片描述
在这里插入图片描述

<2>、解压 jpegsrc.v9e.tar.gz 到安装目录

代码语言:javascript
复制
tar -xf jpegsrc.v9e.tar.gz
ls
在这里插入图片描述
在这里插入图片描述

<3>、配置 进入其目录,执行:

代码语言:javascript
复制
cd jpeg-9e/
./configure --prefix=/home/Gnep/licheepi_zero/tools CC=arm-linux-gnueabihf-gcc --host=arm-linux --enable-shared --enable-static

  • 其中 --prefix 选项是配置安装的路径,如果不配置该选项,安装后可执行文件默认放在 /usr/local/bin,库文件默认放在 /usr/local/lib,配置文件默认放在/usr/local/etc,其它的资源文件放在/usr/local/share,比较凌乱。 用 --prefix 选项的另一个好处是卸载软件或移植软件。当某个安装的软件不再需要时,只须简单的删除该安装目录,就可以把软件卸载得干干净净;移植软件只需拷贝整个目录到另外一个机器即可(相同的操作系统)。
  • 其中 CC 选项是用来选择你想使用的 C 编译器的绝对路径
  • 其中 --host 选项指需要运行的位置,默认为 build,也就是本机编译出来的程序,由本机使用;当本机编译出来的程序要在 arm 板子上运行时,就要设置为 arm-linux
  • --enable-shared:生成动态链接库
  • --enable-static:生成静态链接库
在这里插入图片描述
在这里插入图片描述

<4>、编译

代码语言:javascript
复制
make
在这里插入图片描述
在这里插入图片描述

<5>、安装

代码语言:javascript
复制
make install
在这里插入图片描述
在这里插入图片描述

tools 目录下的文件为现在如下:

在这里插入图片描述
在这里插入图片描述

后面我们需要将 lib 目录下的 libjpeg.so.9 和 libjpeg.so.9.5.0 拷贝到开发板的 /usr/lib 目录中,将 include 目录下的头文件拷贝到我们需要编译的 C 代码的目录下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

以上 jpeglib 库移植完成。

二、jpeg 图片解压缩过程和压缩过程

jpeg/jpg 格式图片显示,经过有损压缩的图片文件格式,文件较小,获取颜色数据需要解压

1、jpeg 解压缩过程

  • 打开设备文件和图片文件
    • int lcd_fd = open(“/dev/fb0”, O_RDWR);
    • FILE *infile = fopen(argv[1], “r+”);
  • 为jpeg对象分配空间并初始化
    • jpeg_create_decompress(&cinfo);
  • 指定解压缩数据源
    • jpeg_stdio_src(&cinfo, infile);
  • 为解压缩设定参数,包括图像大小,颜色空间
    • cinfo.scale_num = 1; //分子
    • cinfo.scale_denom = n; //分母
  • 开始解压缩
    • jpeg_start_decompress(&cinfo);
  • 取出数据(做相关的应用)
    • jpeg_read_scanlines(&cinfo, (JSAMPARRAY)&buffer, 1);
    • 将每行数据显示到LCD
  • 解压缩完毕
    • jpeg_finish_decompress(&cinfo);
  • 释放资源
    • jpeg_destroy_decompress(&cinfo);
    • munmap(p, lcd_wlcd_hlcd_b);
    • close(lcd_fd);
    • fclose(infile);
    • free(buffer);

2、jpeg 压缩过程

  • 为jpeg对象分配空间并初始化
  • 指定图像输出目标
  • 为压缩设定参数,包括图像大小,颜色空间
  • 开始压缩
  • 写入数据(做相关的应用)
  • 压缩完毕
  • 释放资源

三、编译 C 源码

1、源码展示

imageshow.c

代码语言:javascript
复制
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <stdbool.h>
#include "jpeglib.h"
int main(int argc, char const *argv[])
{
	
	if (argc != 2)
	{
		printf("./可执行文件 <jpeg格式图片文件>\n");
		return -1;
	}

	//打开液晶屏
	int lcd_fd = open("/dev/fb0", O_RDWR);
	if (lcd_fd == -1)
	{
		perror("open");
		return -1;
	}

	//获取液晶屏信息
	struct fb_var_screeninfo vinfo;
	ioctl(lcd_fd, FBIOGET_VSCREENINFO, &vinfo); // 获取可变属性
	int lcd_w = vinfo.xres;
	int lcd_h = vinfo.yres;
	int lcd_b = vinfo.bits_per_pixel/8;
	printf("该液晶屏宽:%d,高:%d, 每个像素点%d个字节\n", lcd_w, lcd_h, lcd_b);

	//进行内存映射
	int *p = mmap(NULL, lcd_w * lcd_h * lcd_b, PROT_WRITE | PROT_READ, MAP_SHARED, lcd_fd, 0);
	if (p == (void *)-1)
	{
		perror("mmap");
		return -2;
	}

    // 刷黑屏幕
    memset(p, 0x00, 800 * 480 * 4); 

	//(1)为jpeg对象分配空间并初始化
	struct jpeg_decompress_struct cinfo;	//解压jpeg的对象结构体
	struct jpeg_error_mgr jerr;				//定义错误结构体
	
	cinfo.err = jpeg_std_error(&jerr);		//错误处理结构体绑定
	jpeg_create_decompress(&cinfo);			//初始化jpeg的对象结构体

	//(2)指定解压缩数据源
	FILE *infile = fopen(argv[1], "r+");
	if (infile == NULL)
	{
		perror("fopen jpeg");
		return -3;
	}
	jpeg_stdio_src(&cinfo, infile);//指定解压缩数据源

	//(3)获取文件信息
	jpeg_read_header(&cinfo, true);
	
	//(4)为解压缩设定参数,包括图像大小,颜色空间
	int n = 1;			//缩小倍数
	while(cinfo.image_width/n>lcd_w || cinfo.image_height/n>lcd_h)
	{
		n *= 2;
	}

	//设定的缩小倍数
	cinfo.scale_num = 1;		//分子
	cinfo.scale_denom = n;		//分母
	// cinfo.out_color_space = JCS_GRAYSCALE;	//颜色空间
	printf("width1:%d height1:%d\n", cinfo.image_width, cinfo.image_height);//设定之前的宽高

	//(5)开始解压缩
	jpeg_start_decompress(&cinfo);
	printf("width:%d height:%d\n", cinfo.output_width, cinfo.output_height);//设定解压缩之后的宽高

	//(6)取出数据(做相关的应用),安装一行一行去读取的
	//output_components像素点大小
	//申请能够存放一行数据的缓冲区
	int row_size = cinfo.output_width*cinfo.output_components;
	char *buffer = (char *)malloc(row_size);
	//output_scanline当前读取行数
	while(cinfo.output_scanline < cinfo.output_height)
	{
		//按行读取数据
		jpeg_read_scanlines(&cinfo, (JSAMPARRAY)&buffer, 1);
		//将读取到的一行数据进行显示
		int i = 0, j = 0;
		for (;j< cinfo.output_width; i+=3, j++)
		{
			//内存映射的方式
			*(p+(cinfo.output_scanline-1)*lcd_w + j) = buffer[i+0]<<16| buffer[i+1]<<8| buffer[i+2];
		}
	}

	//(7)解压缩完毕
	jpeg_finish_decompress(&cinfo);

	//(8)释放资源
	jpeg_destroy_decompress(&cinfo);
	munmap(p, lcd_w*lcd_h*lcd_b);
	close(lcd_fd);
	fclose(infile);
	free(buffer);

	return 0;
}

2、拷贝需要用到的头文件

C 代码中包含了 jpeglib.h 头文件(#include “jpeglib.h”),因此我们需要拷贝库安装目录下的四个头文件(jconfig.h jerror.h jmorecfg.h jpeglib.h,路径:/home/Gnep/licheepi_zero/tools/include/),到自己应用程序的目录下。

代码语言:javascript
复制
cp /home/Gnep/licheepi_zero/tools/include/* ./
在这里插入图片描述
在这里插入图片描述

3、编译 C 代码

编译应用程序时,要增加动态库的链接-ljpeg 选项

代码语言:javascript
复制
arm-linux-gnueabihf-gcc imageshow.c -o imageshow -L /home/Gnep/licheepi_zero/tools/lib/ -ljpeg
在这里插入图片描述
在这里插入图片描述

四、验证测试

1、拷贝相关文件到开发板

①、将 imageshow、libjpeg.so.9、libjpeg.so.9.5.0拷贝到 tftpboot 目录中

代码语言:javascript
复制
cp imageshow /tftpboot/
cp /home/Gnep/licheepi_zero/tools/lib/*.so.* /tftpboot/
在这里插入图片描述
在这里插入图片描述

②、将 imageshow 、777.jpg、888.jpeg 拷贝到开发板上,将库安装目录下的 lib 目录下的 libjpeg.so.9 和 libjpeg.so.9.5.0 拷贝到开发板的 /usr/lib 目录中

代码语言:javascript
复制
tftp -g -l 777.jpg 192.168.25.25
tftp -g -l 888.jpeg 192.168.25.25
tftp -g -l imageshow 192.168.25.25
tftp -g -l libjpeg.so.9 192.168.25.25
tftp -g -l libjpeg.so.9.5.0 192.168.25.25
cp libjpeg.so.9 /usr/lib
cp libjpeg.so.9.5.0 /usr/lib
在这里插入图片描述
在这里插入图片描述

2、显示图片

①、雪山照(800 * 480)

代码语言:javascript
复制
./imageshow 777.jpg 
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

②、风景照(480* 272)

代码语言:javascript
复制
./imageshow 888.jpeg
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、资源自取

方式1:github 链接

https://github.com/Gnepuil79/licheepi.git

方式2:百度网盘

链接:https://pan.baidu.com/s/1GWuML5BpRJZ0MneXq9u2Gw 提取码:td2e

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、jpeglib 库移植
    • 1、jpeglib 库下载
      • 2、安装 jpeglib 库
      • 二、jpeg 图片解压缩过程和压缩过程
        • 1、jpeg 解压缩过程
          • 2、jpeg 压缩过程
          • 三、编译 C 源码
            • 1、源码展示
              • 2、拷贝需要用到的头文件
                • 3、编译 C 代码
                • 四、验证测试
                  • 1、拷贝相关文件到开发板
                    • 2、显示图片
                    • 五、资源自取
                      • 方式1:github 链接
                        • 方式2:百度网盘
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档