沙丁鱼介绍

首页 » 常识 » 预防 » 正点原子战舰V3第四十六章图片显示实验
TUhjnbcbe - 2023/7/4 20:31:00
北京看的好白癜风的医院 https://wapyyk.39.net/bj/zhuanke/89ac7.html

在开发产品的时候,很多时候,我们都会用到图片解码,在本章中,我们将向大家介绍如何通过STM32F1来解码BMP/JPG/JPEG/GIF等图片,并在LCD上显示出来。本章分为如下几个部分:

46.1图片格式简介

46.2硬件设计

46.3软件设计

46.4下载验证

46.1图片格式简介

我们常用的图片格式有很多,一般最常用的有三种:JPEG(或JPG)、BMP和GIF。其

中JPEG(或JPG)和BMP是静态图片,而GIF则是可以实现动态图片。下面,我们简单

介绍一下这三种图片格式。

首先,我们来看看BMP图片格式。BMP(全称Bitmap)是Window操作系统中的标准

图像文件格式,文件后缀名为“.bmp”,使用非常广。它采用位映射存储格式,除了图像深

度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大,但是没有失真。

BMP文件的图像深度可选lbit、4bit、8bit、16bit、24bit及32bit。BMP文件存储数据时,

图像的扫描方式是按从左到右、从下到上的顺序。

典型的BMP图像文件由四部分组成:

1,位图头文件数据结构,它包含BMP图像文件的类型、显示内容等信息;

2,位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信

3,调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24

位的BMP)就不需要调色板;

4,位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接

使用RGB,而其他的小于24位的使用调色板中颜色索引值。

关于BMP的详细介绍,请参考光盘的《BMP图片文件详解.pdf》。接下来我们看看JPEG

文件格式。

JPEG是JointPhotographicExpertsGroup(联合图像专家组)的缩写,文件后辍名为“.jpg”

或“.jpeg”,是最常用的图像文件格式,由一个软件开发联合会组织制定,同BMP格式不

同,JPEG是一种有损压缩格式,能够将图像压缩在很小的储存空间,图像中重复或不重要

的资料会被丢失,因此容易造成图像数据的损伤(BMP不会,但是BMP占用空间大)。尤

其是使用过高的压缩比例,将使最终解压缩后恢复的图像质量明显降低,如果追求高品质图

像,不宜采用过高压缩比例。但是JPEG压缩技术十分先进,它用有损压缩方式去除冗余的

图像数据,在获得极高的压缩率的同时能展现十分丰富生动的图像,换句话说,就是可以用

最少的磁盘空间得到较好的图像品质。而且JPEG是一种很灵活的格式,具有调节图像质量

的功能,允许用不同的压缩比例对文件进行压缩,支持多种压缩级别,压缩比率通常在10:

1到40:1之间,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。比如可以

把1.37Mb的BMP位图文件压缩至20.3KB。当然也可以在图像质量和文件尺寸之间找

到平衡点。JPEG格式压缩的主要是高频信息,对色彩的信息保留较好,适合应用于互联网,

可减少图像的传输时间,可以支持24bit真彩色,也普遍应用于需要连续色调的图像。

JPEG/JPG的解码过程可以简单的概述为如下几个部分:

1、从文件头读出文件的相关信息。

JPEG文件数据分为文件头和图像数据两大部分,其中文件头记录了图像的版本、

长宽、采样因子、量化表、哈夫曼表等重要信息。所以解码前必须将文件头信息读出,

以备

图像数据解码过程之用。

2、从图像数据流读取一个最小编码单元(MCU),并提取出里边的各个颜色分量单元。

3、将颜色分量单元从数据流恢复成矩阵数据。

使用文件头给出的哈夫曼表,对分割出来的颜色分量单元进行解码,把其恢复成8

×8的数据矩阵。

4、8×8的数据矩阵进一步解码。

此部分解码工作以8×8的数据矩阵为单位,其中包括相邻矩阵的直流系数差分

解码、使用文件头给出的量化表反量化数据、反Zig-zag编码、隔行正负纠正、反向

离散余弦变换等5个步骤,最终输出仍然是一个8×8的数据矩阵。

5、颜色系统YCrCb向RGB转换。

将一个MCU的各个颜色分量单元解码结果整合起来,将图像颜色系统从YCrCb向

RGB转换。

6、排列整合各个MCU的解码数据。

不断读取数据流中的MCU并对其解码,直至读完所有MCU为止,将各MCU解

码后的数据正确排列成完整的图像。

JPEG的解码本身是比较复杂的,这里FATFS的作者,提供了一个轻量级的JPG/JPEG

解码库:TjpgDec,最少仅需3KB的RAM和3.5KB的FLASH即可实现JPG/JPEG解码,

本例程采用TjpgDec作为JPG/JPEG的解码库,关于TjpgDec的详细使用,请参考光盘:6,

软件资料\图片编解码\TjpgDec技术手册这个文档。

BMP和JPEG这两种图片格式均不支持动态效果,而GIF则是可以支持动态效果。最

后,我们来看看GIF图片格式。

GIF(GraphicsInterchangeFormat)是CompuServe公司开发的图像文件存储格式,

年开发的GIF文件格式版本号是GIF87a,年进行了扩充,扩充后的版本号定义为GIF89a。

GIF图像文件以数据块(block)为单位来存储图像的相关信息。一个GIF文件由表示图形

/图像的数据块、数据子块以及显示图形/图像的控制信息块组成,称为GIF数据流(Data

Stream)。数据流中的所有控制信息块和数据块都必须在文件头(Header)和文件结束块(Trailer)

之间。

GIF文件格式采用了LZW(Lempel-ZivWalch)压缩算法来存储图像数据,定义了允许用

户为图像设置背景的透明(transparency)属性。此外,GIF文件格式可在一个文件中存放多幅

彩色图形/图像。如果在GIF文件中存放有多幅图,它们可以像演幻灯片那样显示或者像动

画那样演示。

一个GIF文件的结构可分为文件头(FileHeader)、GIF数据流(GIFDataStream)和文件终

结器(Trailer)三个部分。文件头包含GIF文件署名(Signature)和版本号(Version);GIF数据流

由控制标识符、图象块(ImageBlock)和其他的一些扩展块组成;文件终结器只有一个值为

0x3B的字符(;)表示文件结束。

关于GIF的详细介绍,请参考光盘GIF解码相关资料。图片格式简介,我们就介绍到

这里。

46.2硬件设计

本章实验功能简介:开机的时候先检测字库,然后检测SD卡是否存在,如果SD卡存

在,则开始查找SD卡根目录下的PICTURE文件夹,如果找到则显示该文件夹下面的图片

文件(支持bmp、jpg、jpeg或gif格式),循环显示,通过按KEY0和KEY2可以快速浏

览下一张和上一张,KEY_UP按键用于暂停/继续播放,DS1用于指示当前是否处于暂停状

态。如果未找到PICTURE文件夹/任何图片文件,则提示错误。同样我们也是用DS0来指

示程序正在运行。

所要用到的硬件资源如下:

1)指示灯DS0和DS1

2)KEY0、KEY2和KEY_UP三个按键

3)串口

4)TFTLCD模块

5)SD卡

6)SPIFLASH

这几部分,在之前的实例中都介绍过了,我们在此就不介绍了。需要注意的是,我们在

SD卡根目录下要建一个PICTURE的文件夹,用来存放JPEG、JPG、BMP或GIF等图片。

46.3软件设计

打开上一章的工程,首先在HARDWARE文件夹所在的文件夹下新建一个PICTURE的

文件夹。在该文件夹里面新建bmp.c、bmp.h、tjpgd.c、tjpgd.h、integer.h、gif.c、gif.h、piclib.c

和piclib.h等9个文件。并将PICTURE文件夹加入头文件包含路径。

其中bmp.c和bmp.h用于实现对bmp文件的解码;tjpgd.c和tjpgd.h用于实现对jpeg/jpg

文件的解码;gif.c和gif.h用于实现对gif文件的解码;这几个代码太长了,所以我们在这里

不贴出来,请大家参考光盘本例程的源码,我们打开piclib.c,在里面输入如下代码:

_pic_infopicinfo;//图片信息

_pic_phypic_phy;//图片显示物理接口

//lcd.h没有提供划横线函数,需要自己实现

voidpiclib_draw_hline(u16x0,u16y0,u16len,u16color)

if((len==0)

(x0lcddev.width)

(y0lcddev.height))return;

LCD_Fill(x0,y0,x0+len-1,y0,color);

//填充颜色

//x,y:起始坐标

//width,height:宽度和高度。

//*color:颜色数组

voidpiclib_fill_color(u16x,u16y,u16width,u16height,u16*color)

LCD_Color_Fill(x,y,x+width-1,y+height-1,color);

//画图初始化,在画图之前,必须先调用此函数

//指定画点/读点

voidpiclib_init(void)

pic_phy.read_point=LCD_ReadPoint;//读点函数实现,仅BMP需要

pic_phy.draw_point=LCD_Fast_DrawPoint;//画点函数实现

pic_phy.fill=LCD_Fill;//填充函数实现,仅GIF需要

pic_phy.draw_hline=piclib_draw_hline;//画线函数实现,仅GIF需要

pic_phy.fillcolor=piclib_fill_color;//颜色填充函数实现,仅TJPGD需要

picinfo.lcdwidth=lcddev.width;//得到LCD的宽度像素

picinfo.lcdheight=lcddev.height;//得到LCD的高度像素

picinfo.ImgWidth=0;//初始化宽度为0

picinfo.ImgHeight=0;//初始化高度为0

picinfo.Div_Fac=0;//初始化缩放系数为0

picinfo.S_Height=0;//初始化设定的高度为0

picinfo.S_Width=0;//初始化设定的宽度为0

picinfo.S_XOFF=0;//初始化x轴的偏移量为0

picinfo.S_YOFF=0;//初始化y轴的偏移量为0

picinfo.staticx=0;//初始化当前显示到的x坐标为0

picinfo.staticy=0;//初始化当前显示到的y坐标为0

//快速ALPHABLENDING算法.

//src:源颜色

//dst:目标颜色

//alpha:透明程度(0~32)

//返回值:混合后的颜色.

u16piclib_alpha_blend(u16src,u16dst,u8alpha)

u32src2;

u32dst2;

//Convertto32bit

-----GGGGGG-----RRRRR------BBBBB

src2=((src16)

src)0x07E0F81F;

dst2=((dst16)

dst)0x07E0F81F;

//PerformblendingR:G:Bwithalphainrange0..32

//Notethatthereasonthatalphamaynotexceed32isthatthereareonly

//5bitsofspacebetweeneachR:G:Bvalue,anyhighervaluewilloverflow

//intothenext

1
查看完整版本: 正点原子战舰V3第四十六章图片显示实验