原创 单片机矢量图形显示方法.

2021-2-4 09:02 10576 47 13 分类: MCU/ 嵌入式

罗昊

摘要 使用图形界面会提高产品的外观及操作便利性,而图形数据需要占用大量的存储空间。对比按像素方式与矢量方式图像。将图形矢量化存储能节省空间。使用SVG格式将图形编码存储,顺序解析矢量图形数据,配合常用图形用户界面,增加贝塞尔曲线绘制函数,将图片绘制出来。使用矢量方法容易实现放大、缩小和动画效果。

关键字:矢量图形、图形用户界面、单片机

Vector graphic storage and display by MCU

Luohao Beijing KellyMed co.,ltd.

Abstract Use GUI improve convenient and get good appearance, generally, graphic data consume massive storage. Compare bit and vector graphic, Use vector method can save memory. Graphic save in SVG format, serial resolve vector data, along with Bessel curve extend GUI to draw graphic. It is easy to implement some effect such as magnify, animation.

Key words: Vector graphic, GUI, MCU

引言

在产品中使用GUI已经成为驱势。随着LCD屏分辨率提高,色彩更丰富。用于显示的图片需要大量的存储空间。一幅320*240的图片,每个像素占一个字节,需要占用76KB。还需要存储8位调色板接近1KB空间。这对于捉襟见肘的单片机存储资源显然是无法接受的。即使使用如JPEG压缩图片,图片解码时需要的RAM资源也很多。如果使用矢量方法进行图形处理,存储与处理都会有较大的改善,并且容易实现一些如扩大缩小,动画等功能。

图片存储方式

以点阵方式处理图片是当前常规的方法,图片是按点存储,按点处理。一幅多大尺寸的图形就需要多大尺寸的存储空间。单片机常用的图形用户界面如μcgui[1]一般都能提供GUI_DrawBitmap这样的函数。按点读取颜色数据,索引调色板中的颜色值,然后写到显示存储器中。

矢量处理方式将图片分成椭圆弧、多边形和路径。其中路径以直线,曲线组成,参照SVG文件标准[2],以文本的形式存储图像。格式示例如下:以命令开头后跟点座标参数。

所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。使用相对定位仅存储差值能缩小存储空间。为保证必要的精度,所有的座标用1位小数表示。以上表方式将图形编码。图形越简单需要的存储空间越小。

如图1所示,a 128*128的图像,如果使用2bit 表示一个像素位,128*128的图像需要4K存储空间。以矢量方式存储,由两个路径一个多边形一个椭圆组成,占用空间不超过0.5K

图形编码数据结构

定义一个结构体描述图形,包含数据类型,颜色,数据指针和下一个数据的指针。

  1. typedef struct VectList{
  2. uint8_t type; //类型,指示数据类型为椭圆弧、多边形或路径
  3. uint32_t fillcolor; //填充颜色值,按RGB
  4. uint32_t strokecolor; //边线颜色
  5. uint32_t strokewidth; //边线宽度
  6. uint8_t *PicStr; //图片数据指针
  7. struct VectList *next; //指向下一个
  8. };

图像数据以结构体的方式,存储在结构体内,结构体中包含指向一下一条数据结构的指针,最后一条指向空指针。形成单向链表。如图2所示。

数据解析

显示一幅矢量图的过程如下,首先获取指向第一条图片记录的结构,如果类型为椭圆或多边形,从PicStr中取得参数,调用画圆,画多边型的函数绘制图片,调用圆填充,多边形填充函数填充图片。如果类型为路径。需要先找到M获得起点座标 ,依次寻找线形,如果为Ll,获取后面的数据作为 调用画线函数,画直线。如果为c获取后面的数据 作为控制点, 为终点,调用绘图函数三次贝塞尔曲线函数绘制图片。其它数据依此类推处理。画线完毕后,再调用填充函数填充图片。所有操作顺序处理,前后基本无关联。

绘图函数

从表中可以看出,需要一些绘图函数来实现矢量图绘制的功能,参考μcgui[1],在核心中会提供画点,线,椭圆,圆弧,多边形等函数。但没有二次和三次贝塞尔曲线的函数。构造一个函数如下:

可知,只要规定好起点终点和中间的控制点,变化参数t就能计算出中间的任意点的座标。为减少计算量,参数t的变化越少越好,可以依据点坐标之间的差值取大值作为点数。确定好点数后,线性变化t求出一系列座标点。用画线函数将这些点连起来就能得到满意的效果。

颜色填充

按上述方法,路径中的贝塞尔曲线实际上已经变换为分段直线,整个路径实际上已经成为由一系列顶点构成的多边形。在画路径的过程中,需要将原有顶点以及计算得到的顶点座标存储成一个阵列。目前应用较广的多边形区域填充算法是标准扫描线算法和边填充算法,扫描线算法需要存储一系列边表,用类似于扫描的方式,将边表之间的区域画线填充,边填充算法则是在原有的边的基础上往内部缩进填充所有内部区域。可以使用GUI自带的多边形填充函数GUI_FillPolygon完成填充工作。

一些特殊效果

绘图中需要一些特殊效果如放大,缩小,动画等。使用矢量方式处理图形,进行放大缩小具有无可比拟的优势。所有的座标只需要按照需要的倍数进行乘积变换。甚至可以进行小数位放大缩小,不会有边沿锯齿产生。产生动画效果,需要可以将需要动作的部件独立存储成矢量,在绘制动画之前,将图形拼合成矢量序列。然后按新的矢量序列绘制,即可产生动画效果。

图片数据生成

可以使用矢量图形编辑工具,将所需要的图片转换成矢量图形,然后存储为SVG文本格式的文件。从文件中摘取所需要的内容,按上面定义的数据结构组成图片数据。

结论

在实际应用中发现,使用矢量方法处理图形,如显示产品LOGO,绘制产品线框图使用说明,显示大字号的文字,对节省存储空间,提高显示性能都特别有效。

作者: southcreek, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-408807.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论1条评论)

登录后参与讨论

moniqiuwen 2021-2-8 16:44

代码后面第二段图标没有显示
相关推荐阅读
southcreek 2024-07-08 11:38
接地不良导致的故障分析
这个电路的控制板需要连接显示板和识别板。5V 供电和串行控制连到显示板,显示板再连接到识别板。识别板上电位器使用一个LDO供电,将输入的5V转成3.3V。当电位器滑动时,输出电压在0~3.3V之间。...
southcreek 2024-06-26 09:15
【EMC整改】带辅助加热的滴速控制器辐射抗扰整改
这个滴速式的输液泵使用一个红外线发射和接收装置,当有液滴通过时,会扰动检测信号,识别这个扰动检测到液滴滴下,获得滴壶中的液滴速度,调整阀门大小,实现输液速度控制。控制器还配备一根加热条,用于输液时对药...
southcreek 2024-06-06 08:52
QT 使用QSettings 操作ini文件配合表格操作
这个项目可以演示 使用QSetting 读取或写入 ini文件。并使用tablewidget 显示。Ini文件的格式如下,这个文件可以事先编写。也可以在程序中生成。有一个大类,下面有一个小类使用等号设...
southcreek 2024-05-27 16:18
差分输入ADC的单端到差分转换器驱动设计
单端信号需要转换成差分信号,以便使用ADC进行转换。这个就所谓的ADC驱动电路。需要的结果为Vp = Vcm + Vi/2Vn = Vcm – Vi/2这样 Vp – Vn = Vi使用简单的加法器和...
我要评论
1
47
关闭 站长推荐上一条 /2 下一条