11、数码相框编写程序之MainPage显存管理与页面规划

2023-10-12 07:59

本文主要是介绍11、数码相框编写程序之MainPage显存管理与页面规划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1、显存的分配和获取
    • 1.1、构造显存链表的结构体
    • 1.2、显存分配函数
      • 1、将我们自己分配的显存加入显存链表
      • 2、 将LCD 实际设备FB 显存加入链表
    • 1.3、显存获取函数
  • 2、显示页面图标函数框架构思
  • 3、编写MainPage页面
    • 3.1、获得显存
    • 3.2、描画数据
      • 1、判断或得到的显存是否已经存在像素数据
      • 2、 获得 LCD 的分辨率
      • 3、确定缩放尺寸
      • 4、首张图标在 LCD 的位置
      • 5、提供缩放后的目标图标的图片数据描述结构体
      • 6、定义一个图标位置描述结构体
      • 7、循环获取原始图片的像素数据,图标的左边数据,缩放、合并
      • 8、释放空间和修改显存数据状态标志位
    • 3.3、数据刷入LCD
    • 3.4、解放显存
  • 4、输入功能
    • 4.1、修改事件类型结构体
    • 4.2、修改输入设备的获取事件函数
    • 4.3、实现对应页面中获取事件并处理的部分
  • 5、测试
    • 5.1、修改之前的代码
    • 5.2、启动开发板

上一节:10、数码相框编写程序之图标显示

下一节:12、数码相框编写程序之效果演示与代码讲解

在上一小节中实现了图标的显示,基本工作就准备好了。现在要来做的是显示下面这些页面:
在这里插入图片描述
先做主页面的显示:
在这里插入图片描述
我们要在显示main_page.c页面的三个图标出来,其实完成的就是我们之前每个页面的框架中的第一步显示页面,即完成如下截图部分的代码。
在这里插入图片描述

1、显存的分配和获取

在写这个代码之前,我们先来了解一下硬件上面是怎么回事:不管你用的是什么开发板,在我们的板子上面,2440 也好或者其他单板也好,里面会有 LCD 控 制 器 或 者 称 为 显 卡 ,外 面 接 有LCDLCD 控制器或者显卡上面对应要有显存。我们写显示器的驱动程序的时候会在内存里面分配一块所谓的显存,在我们这里称为 framebuffer。而 LCD 控制器或者显卡会从 framebuffer 里把数据取出来,发给 LCD。当我们想显示图片的话,直接把图片写到 framebuffer 里就可以了。

那我们写应用程序时怎么做呢?可以先打开驱动程序,得到这块framebuffer,然后就可以在这块显存里面直接写数据了。但是这样有缺点,如果你的程序运行得很慢,当你在 LCD 上面描图片的时候就会发现是一行一行很慢地描。就是说内容更新的很慢。

那我们到底一般会这么做呢?会先 malloc 一块内存,这块内存和 framebuffer 的大小是一样的。我们事先将要显示的图片数据全部放到这块内存里,弄好之后再一股脑 memcpyframebuffer 里面。这样 LCD 的图片就一下子更新好了。就不会出现逐行逐行或者逐块逐块地显示了。
在这里插入图片描述
所以针对于每个页面我们要先获得分配好的内存,然后设置里面的内容(主要是RGB数据部分和一些flag),然后写到我们实际的FB的显存中。

代码见:第 1 个 项 目 数 码 相 框 全 部 源 码 _ 图 片 _ 文 档 \ 源 码 ( 含 讲 课 过 程 中 即 时 编 写 的 文 档 )\12. 数 码 相 框 项 目\14.digital_photo_frame_8.4.2_图片_源码\14.digital_photo_frame_8.4.2 节_图片_源码\14.digial_photo_frame

应用程序事先分配好多块内存,用于显存:
在这里插入图片描述

1.1、构造显存链表的结构体

但是要考虑由于我们是嵌入式系统,针对于某些型号可能内存不够用,所以分配多个显存并非对应每种型号都适用的,所以我们要兼容这些型号,我们在构造显存的链表的时候,应该在最头部加上设备实际分配的fb的显存,对应这些内存不够用的设备,我们可以只使用这个显存链表的第一个成员即可,那么对于每个显存链表中结构体的成员应该如何考虑呢?(实际上也就是每个显存里面除了要保存RGB数据供实际的设备显存fb使用,还需要哪些表示来表示和区分这些其余的显存的,比如我现在有5个页面,也就是要分配5个显存,外加一个fb的实际设备的显存,假如我要显示main_page这个页面,我们首先要把main_page页面对应的显存里面对应的数据给fb就可以显示,但是要解决几个问题:怎么从显存链表里面找到main_page的显存呢?main_page里面的显存里面的RGB数据有没有准备好呢?等等),从如上几点考虑,我们的显存链表结构体构造成员如下:

  • 1、由于我们的目的是为了让所有的页面都对应分配一个显存,那样对应每个页面都会有对应的显存保存它的数据,我们之后用户操作返回,或者前进时,在每个页面的显存就不用再次去设置里面的内容,所以我们需要一个ID来标识每个显存,当用户去返回,或者跳转到另外的页面时,就可以直接利用原来的对应的显存来进行显示里面的数据,所以需要以ID来辨别显存;
  • 2、我们之前有提到过,在用户点击触摸之后,会有一段时间的间隙,我们利用这段间隙,把可能下次要准备的页面通过多线程的方式准备好,所以我们还需要一个成员用来判断这个显存是给主线程使用,还是prepare线程使用的,另外给个初始状态是未被使用的,所以需要一个显存的进程使用状态eVideoMemState
  • 3、我们所分配的显存中主要还是用来存放要显示的每一页的数据,我们需要定义一个标志位来表示这个显存里面的对应的数据的情况,,是已经有了数据,还是正在产生数据,还是空的,成员为ePicState
  • 4、最开始我们说了我们要在链表的头部加上一个实际LCD设备的fb的显存,但是我们如何标识出链表中的成员是不是fb的实际设备显存呢,用标志位bDevFrameBuffer表示;
  • 5、最主要的还是给每个显存里面提供要现实页面的RGB数据,也就是我们之前有定义的T_PixelDatas tPixelDatas
  • 6、最后就是要提供链表的指向下一个链表的成员struct VideoMem *ptNext

最终的结构体定义如下:
在这里插入图片描述
构造完显存的链表的结构体之后,我们就要实现这个链表,我们肯定要提供一个分配显存的函数int AllocVideoMem(int iNum),其次我们最终是要把链表里面的某一个显存成员memcpyfb实际的显存,所以我们还需要一个从链表中提取显存的函数,我们分配显存肯定能是在应用层最开始就配分的,比如说我们要分配5块显存,里面的具体内容在最开始分配的时候基本上都是一样的,比如ID都设置为0,当具体的页面比如main_page去取显存的时候,发现5个的ID都是0,就会随机取一块然后再具体分配ID和对应的页面的RGB数据给显存,下次相同的页面只需要再取到同样的ID的显存就可以了。

1.2、显存分配函数

提供一个分配显存的函数给最顶层使用,我们先来看分配显存的函数如何实现。

1、将我们自己分配的显存加入显存链表

针对于我们要分配的显存,我们肯定是用malloc来分配,那么要分配多大呢?要注意的是并非sizeof(T_VideoMem)这么大,T_VideoMem这个结构体只是用来标识我们的分配的显存的,里面虽然有定义对应页面的数据的指针,但sizeof(T_VideoMem)并没有包含页面对应数据的大小,所以还要分配对应页面数据的大小,其实我们的数据也就是我们LCD的分辨率的大小:sizeof(T_VideoMem) + LCD的数据大小

  • 1、获取LCD的分辨率
    要获得我们LCD的数据大小,就是要获取我们LCD的分辨率来计算的,我们之前的代码有获取x、y值,但要知道要分配多少个字节,还需要知道bpp参数,所以修改代码:
    在这里插入图片描述
    然后我们就可以获取bpp了:
    在这里插入图片描述
  • 2、然后就是初始化PT_VideoMem ptNew里面成员的各项
    在这里插入图片描述
    PT_VideoMem ptNew中有一个指向对应页面数据的指针,分配到我们链表结构体后面即可:
    在这里插入图片描述
    也就是说我们分配的显存的结构就是前面有个PT_VideoMem类型的显存描述结构体指针,后面紧接着显存的实际页面数据,让PT_VideoMem里面的显存某个指向数据的指针指向后面的实际数据。
  • 3、初始化完成之后就是要这项显存放入链表中
    在这里插入图片描述
    如何理解这样就把新的显存结构体加入了链表呢?
    在这里插入图片描述
    我们每次都让刚定义的结构体的下一项指向链表头部ptNew->ptNext = g_ptVideoMemHead;,然后让链表的头部更新为刚才最后加入的结构体g_ptVideoMemHead = ptNew;这种方式就是链表的头部永远是最后更新的结构体。

2、 将LCD 实际设备FB 显存加入链表

加入完链表之后别忘了我们在链表里面还要添加一个FB的实际设备的显存,对于我们的LCD的真正的设备显存,由于我们在初始化display设备的时候就已经分配了,这里我们只需要分配一个显存链表结构体的大小,然后让显存链表结构体里面的实际像素数据成员指向我们之前分配的LCD的设备显存即可,然后再初始化实际显存对应的链表结构体各项,最后加入链表。

  • 1、分配实际链表显存对应的结构体
    在这里插入图片描述
  • 2、初始化实际显存对应的链表结构体各项
    在这里插入图片描述
  • 3、加入链表
    在这里插入图片描述
    最终的分配显存的代码如下:
    在这里插入图片描述

1.3、显存获取函数

下面来看看取显存的函数,我们肯定是根据ID来取

PT_VideoMem GetVideoMem(int iID, int bCur) {1. 优先: 取出空闲的、ID相同的videomem2. 取出任意一个空闲videomem
}

在这里插入图片描述

2、显示页面图标函数框架构思

回到我们本节的主要目的就是为了显示main_page上面的三个图标,之前的我们完成了准备工作,显存的分配和提取函数,接下来我们看看如何显示图标,也就是完成下面的第一步显示页面:
在这里插入图片描述
创建显示页面的函数,并构思实现的步骤:

  • 1、获得显存:应用层通过调用刚才的分配显存函数,分配了若干个显存,我们们首先要获取一个显存(这个显存可能是已经被使用过的相同ID的显存,也可能是块空显存)。
  • 2、描画数据:我们要将我们的main_page里面的图标对应的像素数据提取出来,经过图片缩放和合并之后,最终将像素数据放到刚才分配的显存中。
  • 3、刷到设备上去:由于我们之前只是把数据放到了我们自己分配的显存中,并没有放到LCD真正的设备FB显存,所以并不会显示,我们需要想之前显存的数据拷贝到FB显存中。
  • 4、解放显存:使用完我们分配的显存之后,我们要把他的状态置为VMS_FREE状态,供给下次或者别人使用,这是不是释放掉而是置标志位而已。

3、编写MainPage页面

上面我们知道针对于每个页面我们要先获得分配好的内存,然后设置里面的内容(主要是RGB数据部分和一些flag),然后写到我们实际的FB的显存,上一节中我们已经写好了分配内存和提取内存的函数,这一节,我们来按照上面的步骤针对于每一页具体的来显示一个一个页面的内容:
在这里插入图片描述
具体的就是实现上面的显示页面的函数:
在这里插入图片描述
应该如何实现上面的函数呢?

3.1、获得显存

在这里插入图片描述
第二参数1,代表这个显存用于主线程,而不是prepare线程。我们这里的ID并不是简单的1,2,3,4,而是根据名字字符串转换为一个int型数据:
在这里插入图片描述

3.2、描画数据

我们要把main_page里面的所有图标的数据经过缩放和合并之后保存到我们的上面一步获得的显存中,那么要缩放和合并的话,我们首先就要知道原始图片的数据和我们想缩放到什么尺寸,其次合并的话我们还要确定我们每个图标在LCD上显示的位置,我们的图片的位置是根据LCD的实际分辨率来按比例设置的。

1、判断或得到的显存是否已经存在像素数据

判断获得到的显存结构体里面对应的像素数据是否已经生成过了,首先要判断显存的里面的RGB数据是否已经存在,只要判断ePicState就行。
在这里插入图片描述

2、 获得 LCD 的分辨率

在这里插入图片描述

3、确定缩放尺寸

在这里插入图片描述
由于我们的原始图片的大小为256*128,我们自己定义下要显示的图片的位置(这是我们自己规划的),如下图:红色的边框就认为是LCD的边界。
在这里插入图片描述
即缩放后的长和宽是多少?(矩形图片只要知道这两个值就好)
在这里插入图片描述
在我们main_page页面中有三个单元要显示,每个大小是一样的,都是:
在这里插入图片描述

4、首张图标在 LCD 的位置

在这里插入图片描述

5、提供缩放后的目标图标的图片数据描述结构体

由于我们知道我们的缩放函数出入的参数是原图片和目标图片的图片数据结构体
在这里插入图片描述
缩放前后bpp值不变(LCDbpp),长宽为缩放后的数据,即如下:
在这里插入图片描述

6、定义一个图标位置描述结构体

我们知道了缩放后目标图片的大小,现就待会要去合并,合并需要提供一个显示起点的左标,我们有3个图标,可以通过定义一个结构体,这个结构体用来描述每个图标应该位于的左边,和图标的名字,然后通过循环去一个个缩放合并。
我们现在自己定义了每个图标的位置,我们对于每个图标抽象出一个结构体来描述这个图标的。我们知道每个图标都是矩形,我们只要知道了图标的左上和右下的坐标就基本上知道了图标的位置。在page_manager.h里面定义如下结构体:
在这里插入图片描述
接下来我们在main_page.c里面针对于每个图标都定义一个该结构体,所以定义一个结构体数组:
在这里插入图片描述
一开始我们都设置前面的坐标都为0,由于我们待会要循环去显示给每个图标赋值,那么我们怎么知道图标结尾了呢?我们就添加了最后一项,每个成员都设置为空。现在我们就是要在描绘图标里面把前面的上面的结构体的前面几项描绘出来,所以我们直接把每个图标作为参数传递给显示的函数就比较方便了:
在这里插入图片描述
这也是我们这个函数参数的由来,知道了这些我们就可以设置我们显存中关于图片的信息的数据了。

7、循环获取原始图片的像素数据,图标的左边数据,缩放、合并

由于我们每个图标只有Y值会变,X不变(右下的x,y都是根据左上来计算的)我们设定好了缩放后的图片的数据,现在要获取原始图片的像素数据
在这里插入图片描述
分析上面的重点部分,上面的:
在这里插入图片描述
他需要传入一个原始图片的数据信息和新图片的数据信息,那么我们如何获得一个原始图片的信息呢?我们之前8.3.3测试的main函数里面是先open一个文件,然后再去获取的,现在我们就参照之前的步骤:
在这里插入图片描述
定义一个函数,传入图标的名字来获取对应图标的像素数据,该函数的步骤:

  • 1、定义一个文件的描述结构体,里面有文件的路径、大小、描述符、还有一个指针(是用来指向文件的内容的)
    在这里插入图片描述
  • 2、通过传入的图标名构造正确的文件路径,并保存在上面的一个结构体变量中
    在这里插入图片描述
  • 3、构造一个MapFile去打开刚才路径的图标文件,并将文件的内容映射到内存中
    在这里插入图片描述
    MapFile的实现如下:
    在这里插入图片描述
    这里就让我们的传入的PT_FileMap变量中的一个指针pucFileMapMem指向了我们分配的内存,而这个内存里面的数据就是文件内容,我们想要知道文件的像素数据,就只要操作这个pucFileMapMem就可以了,同时构造一个取消映射的函数:
    在这里插入图片描述
  • 4、之后去解析刚才的放到内存的文件的数据,判断是否为bmp格式文件,通过判断文件内容的第一个和第二个内容数据是否为424d
    在这里插入图片描述
    g_tBMPParser这个结构体变量是个全局结构体变量,都可以用。
  • 5、在获取原始图片的像素的数据之前,由于GetPixelDatas函数需要对不同的bpp有不同的数据返回,我们要先获取lcdbpp
    在这里插入图片描述

8、释放空间和修改显存数据状态标志位

在这里插入图片描述

3.3、数据刷入LCD

我们前面已经获取完显存,然后把要显示的数据放到了我们获取到的显存上,现在我们要把这个显存的数据复制到FB的实际显存上才能显示,构造如下函数来实现:
在这里插入图片描述
函数实现如下:
在这里插入图片描述
要先判断得到的显存不是实际的FB的显存,因为我们的FB显存也是在显存链表中的。

3.4、解放显存

在这里插入图片描述
实现如下:
在这里插入图片描述

4、输入功能

在上一小节里面,我们描绘了在 LCD 上显示的主页面的三个图标,这一节讲输入功能。
在这里插入图片描述
我们前面完成了显示页面,按照流程我们还有创建parepare线程获取输入事件处理,我们先做后面一个环节,然后就可以调试了。
在这里插入图片描述
现在我们要实现,当用触摸笔在 LCD 上点击图标时,图标就要改变一下颜色。当松开触摸笔时,图标恢复原来的颜色。

4.1、修改事件类型结构体

我们这个要产生触摸事件的代码目前还是参照在电子书的基础上的代码,我们回顾下电子书关于触摸事件的代码,input文件里面定义的结构体是:
在这里插入图片描述
进入产生事件的函数的代码,发现是根据我们的触摸位置来产生翻页等几个简单的动作,肯定是不能满足我们目前的需求的:
在这里插入图片描述
对于我们数码相框而言,我们需要知道更精确的触摸位置是点下还是松开,我们现在要修改获取触摸事件的函数,先修改我们的事件类型的结构体:
在这里插入图片描述
之前我们只抽象出事件的时间值,还有事件触发的类型(标准输入还是ts),还有事件值(翻页等动作)现在我们要定义一个抽象出一个事件的结构体,他既能描述触摸点事件和按键事件,对于触摸点事件,我们要有触摸的x,y坐标,按下还是松开,对于按键事件,要有按下和松开,还有是哪个按键按下,结构体如下:
在这里插入图片描述
其实上面的这个结构体可以参考tslib,上面的结构体中
类别:当我的type是触摸屏的时候,我们用到成员有x、y、还有压力
当我的type是按键或者标准输入的时候,用到key和压力

上面的结构体中的x、y坐标对触摸有用;
上面的压力值对于按键和触摸都用,按键松开时压力为0,按下为1;
上面的IKEY对按键有用。

4.2、修改输入设备的获取事件函数

修改完结构体后,我们修改touchscreen.c中的TouchScreenGetInputEvent函数,之前是根据触摸在LCD的位置来返回事件,现在我们要在获取事件后返回真实的数据,也就是上面定义的事件的结构体:
在这里插入图片描述
对于触摸屏基本就这样就可以了,接下来我们改下标准输入的事件获取函数StdinGetInputEvent,由于我们目前还没确定每个图标对应哪个按键来触发,所以暂时先不管StdinGetInputEvent,我们先暂时只考虑从触摸屏来触发事件。

4.3、实现对应页面中获取事件并处理的部分

接下来我们要看下我们的page里面的main_page.c,我们要通过获取到事件,然后进行动作:
在这里插入图片描述
接下来我们来实现MainPageGetInputEvent函数,肯定这个函数里面也是调用我们之前input里面的int GetInputEvent(PT_InputEvent ptInputEvent)所以我们传入一个事件类型的结构体,用来保存触发的事件的相关信息,另外我们要判断触发的事件为我们页面中的哪个图标,所以需要传入我们的图标描述的结构体PT_Layout atLayout确认了函数的参数,继续构想要如何实现main_page里面的获取事件函数

  • 1、通过input层提供的GetInputEvent来获取事件
    在这里插入图片描述
    没获取到事件就休眠,有事件后触发,由于现在只考虑触摸屏触发,我们要知道我们触摸到了哪一个图标,由于我们之前有定义过每个页面中的每个图标的左上和右下的坐标的结构体:
    在这里插入图片描述
    我们就可以根据这个结构体来判断我们的触摸的位置是否在这个图标的坐标之内来判断,由于我们要返回一个哪个Layout的图标被触发了,所以我们把ptInputEvent里面新增一个Layout成员。
  • 2、根据mian_page里面的图标的坐标和刚才通过事件获取函数记录到的x,y等信息来判断
    在这里插入图片描述
    这个函数返回:事件触发的图标的序号。

接下来返回我们的MainPageRun继续写代码:我们要实现当用触摸笔在 LCD 上点击图标是,图标就要改变一下颜色。当松开触摸笔时,图标恢复原来的颜色。

刚才我们已经可以获取事件,并知道是哪个图标被触摸了,找到了这个图标是否被触摸了之后,那么我们怎么知道他是被点下了还是松开了?针对于我们触发的事件,我们只要按照如下逻辑分类,我们只对所有的触发事件的两个时刻做处理,其余不理会

  • 1、某触摸图标被按下,且之前未被按下
  • 2、某触摸图标未被按下,且之前该图被按下

在这里插入图片描述
我们用bPressed来代表该图标之前是否被按下过,用iIndexPressed来记录触发按键的图标序号。

每次图标的变化动作就将图标的对应的显存的里面的像素数据取反即可(要注意的是这里的的显存是当前用于显示的真正的设备FB显存,而不是给每个页面分配的显存)。

像素取反函数static InvertButton(PT_Layout ptLayout)先获取真正的显存FB
在这里插入图片描述
然后找到要取反的图标的像素数据在FB显存的位置:
在这里插入图片描述
然后一行行取反:
在这里插入图片描述

上一节:10、数码相框编写程序之图标显示

下一节:12、数码相框编写程序之效果演示与代码讲解

5、测试

前面三节讲了 mainpage 的显存管理、页面规划、输入功能。
在这里插入图片描述
现在这一个我们把之前写的程序调试一下,然后在开发板上运行,观察效果。当韦东山录制完这一节之后,会发布一个 8.4.4 源码
在这里插入图片描述
可以跟 8.4.3 源码比较一下,这样就可以看出来做了哪些修改。因为这一节会讲得比较啰嗦,如果你不想从头到尾一句话一句话地改的话,直接比较最终结果。

修改前的代码见:第 1 个项目数码相框全部源码_图片_文档\源码(含讲课过程中即时编写的文档)\12.数码相框项目\14.digital_photo_frame_8.4.3_ 源 码\14.digital_photo_frame_8.4.3 节 _ 源 码\14.digial_photo_frame

修改后的代码见:第 1 个项目数码相框全部源码_图片_文档\源码(含讲课过程中即时编写的文档)\12.数码相框项目\14.digital_photo_frame_8.4.4_源码_文档\14.digital_photo_frame_8.4.4 节_源码_文档\14.digial_photo_frame

以后参考代码时:
8.4.3 里的代码就不要参考了,里面有很多错误。
8.4.4 里的代码可以参考。

5.1、修改之前的代码

修改顶层 Makefile,把所有的警告当做错误处理:
在这里插入图片描述
修改为:
在这里插入图片描述这样就可以编译出一点警告都没有的程序了。顶层 Makefile的其他修改参考说明

修改底层 Makefile: 参考说明文档
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
定位到 132 行:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2、启动开发板

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

上一节:10、数码相框编写程序之图标显示

下一节:12、数码相框编写程序之效果演示与代码讲解

这篇关于11、数码相框编写程序之MainPage显存管理与页面规划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/194434

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2