完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
Graph控件是用于实现图表以及需要绘制图像的控件,该控件在TouchGFX Designer中没有体现,但是可以在工程中自行添加,TouchGFX官方给的Demo中有针对于该部分的Demo,这些Demo可以给大家些帮助,下面针对于该控件给大家详细的介绍下。
CanvasWidget Canvas Widgets和Canvas Widget Renderer是TouchGFX的功能强大且用途广泛的附加组件,它使用相对较少的内存就可以提供流畅,抗锯齿的几何形状图形,同时保持了高性能。但是,渲染几何形状必须被视为相当昂贵的操作,并且如果不小心使用,很容易使微控制器资源紧张。 Canvas Widget Renderer(以下称为CWR)是一种通用的图形API,可为图元提供优化的图形,并自动消除大多数多余的图形。TouchGFX使用CWR绘制复杂的几何形状。几何形状由“画布小部件”定义。TouchGFX随附了许多受支持的Canvas Widget,但就像普通的Widget一样,您可以制作自己的自定义Canvas Widget来满足您的需求。当Canvas Widget定义要由CWR绘制的图形的几何形状时,图形内每个像素的实际颜色由关联的Painter类定义。同样,TouchGFX附带了许多Painter,但是您可以根据自己的需要制作自己的自定义Painter。 TouchGFX中的其他小部件的大小会自动设置。例如,位图小部件将自动获取所包含位图的宽度和高度。因此,足以setXY()在位图小部件上使用以将位图放置在显示器上。 画布小部件没有默认大小,该默认大小可以自动确定并进行初始设置。必须不仅要注意位置,而且还要正确调整窗口小部件的大小,否则“画布”窗口小部件的宽度和高度将为零,并且在显示器上不会绘制任何内容。 因此,不要setXY()使用setPosition()来放置和调整画布小部件的大小,而要使用。另请参阅下面的“自定义画布小部件”,以获取有关如何创建和使用自定义画布小部件的示例。 设置画布小部件的位置和大小后,便可以在其中绘制几何形状。坐标系将在小部件(而不是显示)的左上角具有(0,0),X轴向右延伸,Y轴向下延伸。 Canvas窗口小部件在TouchGFX Designer中也受支持,它使用法简单并具有自动内存分配功能。 CanvasWidget内存分配 TouchGFX Designer中的内存分配 将小部件添加到屏幕的画布时,会自动生成一个内存缓冲区。缓冲区的大小基于具有以下公式的屏幕宽度(Width × 3)× 5。但是,这并非总是适用于所有情况的理想缓冲区大小。因此,可以覆盖缓冲区大小,如下图所示。 用户代码中的内存分配 内存可被分配和设置在target/main.cpp与simulator/main.cpp或可以设置和每画面分配。 static const uint16_t CANVAS_BUFFER_SIZE = 3600;static uint8_t canvasBuffer[CANVAS_BUFFER_SIZE] 定义内存缓冲区大小的静态const,可以在main.cpp或的开头定义实际的内存缓冲区ScreenView.hpp 然后,在任一main()的方法main.cpp或setupScreen()方法ScreenView.cpp中的以下行建立缓冲区可以被添加。 CanvasWidgetRenderer :: setupBuffer (canvasBuffer ,CANVAS_BUFFER_SIZE ); 所需的CWR内存量取决于应用程序中要绘制的形状的最大大小。但是,您可以保留少于最大形状所需的内存。为了处理这种情况,CWR将形状的图纸分成较小的帧缓冲区部分,从而导致稍长的渲染时间,因为在这种情况下,有时不得不多次渲染形状。在模拟器模式下运行时,可以更仔细地调查和微调内存消耗。只需将以下函数调用添加到main.cpp中: CanvasWidgetRenderer :: setWriteMemoryUsageReport (true ); 现在,每当绘制操作完成时,CWR都会报告(在控制台中打印)需要多少内存。对于canvas_widget_example,它可能是“ CWR需要3604字节”(对于第一次绘制操作),然后是“ CWR需要7932字节(缺少4328个字节)”(对于第二次绘制操作)。即使CWR似乎没有足够的内存(在这种情况下,缺少4328字节),应用程序也可以正常运行。这是因为CWR检测到可用内存太少,无法在一次运行中完成复杂的绘制操作。取而代之的是,它将绘制操作分为两个单独的绘制操作,形状将被绘制得很好,但需要更多时间进行渲染。 因此,设置正确的内存缓冲区大小需要在内存和性能(渲染时间)之间进行权衡。好的起始值通常约为3000,但是使用上述技术,通常可以确定更好的值。如果形状太复杂而分配的内存缓冲区太小,则将不会绘制形状的一部分(某些垂直像素线将被跳过),并且有可能根本没有绘制。无论如何,渲染时间都会增加很多。 这意味着,如果您希望您的应用程序以最快的速度渲染CWR图形,则需要分配请求的内存量。但是,如果可以使用较慢的渲染计时器,则可以减少内存缓冲区。 CWR坐标系 TouchGFX中的坐标系通常用于寻址像素,以在显示器上定位位图。位图,文本和其他图形元素都放置在坐标系中,其中(0,0)是左上像素,x轴向右延伸,y轴向下延伸。在CWR中,仅能够使用整数寻址像素是不够的,尽管在特殊情况下这可能就足够了,但通常这还远远不够。为了说明这一点,请考虑一个线宽为1的圆,它必须恰好适合5 x 5像素的框。该圆的中心必须位于(2.5,2.5),半径必须为2,因此中心坐标需要分数。同样,如果圆应适合于6 x 6像素的框,则中心必须位于(3,3),半径必须为2.5,因此此处半径必须为分数。 这种寻址图形坐标的新方法意味着(0,0)的像素中心具有CWR坐标(0.5,0.5)。因此,包含在屏幕左上角像素的框具有以下轮廓:(0,0)->(1,0)->(1,1)->(0,1)->(0 ,0)。 尽管起初看起来似乎很混乱,但很快就变得很自然。当位图的坐标系统处理像素时,画布小部件的相同坐标处理像素之前和上方的间隙。 点、线、面 当创建完画图的画板后就可在其中创建图像, TouchGFX的图像不支持线性的曲率变化,换句话说就是只能通过点去链接线,但是如何能做到曲率的线呢,这时我们可以通过贝塞尔算法,或者其他的曲率算法推算出每一个点的坐标,或者是相隔固定点的坐标,之后在界面上显示出来。 官方提供了两个demo 分别是TouchGFX Demo1 和TouchGFX Demo2,两个demo中都有graph绘制方法的体现,但体现的方法不同,对用CanvasWidget继承程度也不尽相同。 这里我们讲解个内容比较多的TouchGFX Demo1,我会在下一节提出代码。 Demo 首先先看一下该部分代码的调用的方法。 primaryGraph.setXY(graphXOffset, graphYOffset); primaryGraph.setup(graphWidth, graphHeight, Color::getColorFrom24BitRGB(0x24, 0x73, 0xAC), graphBackground.getColor()); primaryGraph.setDotShape(0, 30, 5);//设置折线上点的参数 primaryGraph.setDotBackgroundShape(0, 30, 7);//设置折线上点的背景参数 graphArea.add(primaryGraph); 在此可以看出graph作为一个控件调用方法是一致的,都是先设置x,y的位置,也需要设置画布的宽高,以及转向点或者其他的设置。 这里唯一的不一样的地方是setup()函数,这个函数中除了宽高外还有颜色,颜色的含义则是画笔的颜色,想要作画除了画布同样还需要画笔。至于化成什么样子则是我们掌握的,下面看下setup函数。 void Graph::setup(int newWidth, int newHeight, colortype lineColor, colortype backgroundColor){ setWidth(newWidth); setHeight(newHeight); graphLinePainter.setColor(lineColor); graphAreaPainter.setColor(lineColor, 255); graphDotsPainter.setColor(lineColor); graphDotsBackgroundPainter.setColor(backgroundColor); graphLine.setLinkedGraph(graphArea); graphLine.setLinkedGraph(graphDots); graphLine.setLinkedGraph(graphDotsBackground); graphLine.setPosition(0, 0, getWidth(), getHeight()); graphLine.setPainter(graphLinePainter); graphLine.setBuffer(graphBuffer, NUMBER_OF_POINTS); graphLine.setLineWidth(1); graphLine.setRange(-2, 216, 400, 0); graphArea.setPainter(graphAreaPainter); graphArea.setLineWidth(0); graphDots.setPainter(graphDotsPainter); graphDots.setLineWidth(7); graphDots.setDotShape(0, 90); graphDotsBackground.setPainter(graphDotsBackgroundPainter); graphDotsBackground.setLineWidth(9); graphDots.setDotShape(0, 30); add(graphArea); add(graphLine); add(graphDotsBackground); add(graphDots);} 可以看出,整体采用的画笔以及将其画布放置在一起的过程。 除此之外还有些细节的这里不将展示。需要可以参考官方的代码,我将具体的部分放到这里供大家快速定位。 GraphView.cpp中放的是使用方法,文件夹graph_widget文件夹中放的是控件的源码,大家可以根据需要自己研究下该控件。 注意 本人在开发该部分控件时,会弹出buffer空间不足的提示框,原因则是在新建的工程中未添加画布空间的buffer,所以才会报错,具体请参照本章内容。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1752 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1611 浏览 1 评论
1052 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1666 浏览 2 评论
1924浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
711浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
560浏览 3评论
583浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
544浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 12:44 , Processed in 0.674768 second(s), Total 46, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号