使用GDI对象绘制UI时需要注意的若干细节问题总结
目录
1、一个bitmap不能同时被选进两个dc中
2、CreateCompatibleDC和CreateCompatibleBitmap要使用同一个dc作为参数
3、不能删除已经被选入DC中的GDI对象
4、使用完的GDI对象,要将之释放掉,否则会导致GDI对象泄漏
5、CreateCompatibleBitmap返回错误码8的原因及解决办法(用CreateDIBSection替换CreateCompatibleBitmap)
6、Windows开发人员必须要学会到微软MSDN上查看函数的详细说明
7、最后
C++软件异常排查从入门到精通系列教程(核心精品专栏,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(重点专栏,专栏文章已更新480多篇,持续更新中...)
https://blog.csdn.net/chenlycly/article/details/140824370C++ 软件开发从入门到精通(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)
https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)
https://blog.csdn.net/chenlycly/category_2276111.html 我们在自绘窗口、给控件贴图、绘制文字时会使用到Pen画笔、Brush画刷、Bitmap位图、Font字体、Region区域、DC设备上下文等GDI对象,在使用这些GDI对象要注意一些细节问题,否则会出现一些绘制异常。本文结合多年的项目实践,给大家分享几个使用GDI对象的细节,以供大家借鉴或参考。
1、一个bitmap不能同时被选进两个dc中
我们在使用Pen画笔、Brush画刷、Bitmap位图、Font字体、Region区域等GDI对象绘制之前,需要将它们选进DC设备上下文中,然后通过DC去操作使用。
对于bitmap对象,使用示例如下:
// 先创建位图,然后将位图选进DC中,然后操作DC去完成绘图
HDC hMemDC = ::CreateCompatibleDC( hdc );
HBITMAP hMemBitmap = ::CreateCompatibleBitmap( hdc, rect.GetWidth(), rect.GetHeight() );
::SelectObject( hMemDC, hMemBitmap );
使用bitmap对象时,不能将一个bitmap同时选进两个dc中。
系统API函数SelectObject在MSDN上有明确的说明:
即一个bitmap不能同时被选进两个dc。这个问题我们之前遇到过,因为新手在编写GDI绘制的代码时代码不规范,创建的GDI资源没有释放,导致一个bitmap被选进了两个dc中,导致绘制有问题,始终达不到预期的效果。
2、CreateCompatibleDC和CreateCompatibleBitmap要使用同一个dc作为参数
我们在使用双缓冲绘图时会先创建一个内存DC和内存bitmap,如下:
// CreateCompatibleDC和CreateCompatibleBitmap使用的是同一个参数hdc
HDC hMemDC = ::CreateCompatibleDC( hdc );
HBITMAP hMemBitmap = ::CreateCompatibleBitmap( hdc, rect.GetWidth(), rect.GetHeight() );
但要注意,CreateCompatibleDC和CreateCompatibleBitmap两函数传入的dc对象必须是同一个。
有些人可能会将CreateCompatibleDC返回的dc对象,直接放到CreateCompatibleBitmap参数中,如下:
// 错误:CreateCompatibleBitmap使用CreateCompatibleDC返回的dc句柄
HDC hMemDC = ::CreateCompatibleDC( hdc );
HBITMAP hMemBitmap = ::CreateCompatibleBitmap( hMemDC, rect.GetWidth(), rect.GetHeight() );
这样会导致调用CreateCompatibleBitmap创建的位图是单色位图,只能绘制黑白颜色的效果。
MSDN上CreateCompatibleBitmap API函数说明页面,有下面一段说明:
大体意思是,当一个内存dc被创建时,初始拥有一个尺寸为1x1的单色的位图被选进去。如果这个新创建的内存dc(CreateCompatibleDC函数返回的dc),被用到CreateCompatibleBitmap的参数中用来创建bitmap,那么这个位图将是单色的位图,只能绘制黑白颜色的效果。
之前在开发截图功能时就遇到过,当时截图的背景始终是灰白色的,后来看到上述MSDN上说明才知道原因。
在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)
专栏1:(该精品技术专栏的订阅量已达到570多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)
C++软件调试与异常排查从入门到精通系列文章汇总https://blog.csdn.net/chenlycly/article/details/125529931
本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!
考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!
专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!
专栏2:(本专栏涵盖了C++多方面的内容,是当前重点打造的专栏,订阅量已达220多个,专栏文章已经更新到480多篇,持续更新中...)
C/C++实战进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html
以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、数据结构与算法、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。
专栏3:
C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795
常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!
专栏4:
VC++常用功能开发汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/124272585
将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。
专栏5:
C++ 软件开发从入门到精通(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.html
根据多年C++软件开发实践,详细地总结了C/C++软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。
3、不能删除已经被选入DC中的GDI对象
DeleteObject API函数中,有如下的说明:
即不能删除还在被选入dc中的GDI对象,需要选出后再删除,否则会导致绘制异常。
4、使用完的GDI对象,要将之释放掉,否则会导致GDI对象泄漏
在GDI对象使用完成后要将之删除或释放掉,如果不删除或释放,则会导致GDI泄漏。如果有GDI对象泄漏的代码被频繁地执行,会导致GDI对象在持续的泄漏,当GDI对象总数接近或达到1万个时,就会导致GDI绘图函数调用出现异常,出现窗口绘制不出来等问题,紧接着程序就可能会出现崩溃。很多Windows老程序员可能都遇到过类似的问题。
关于Windows进程的GDI对象数目上限的详细说明,可以查看我的文章:
从注册表看Windows系统进程GDI句柄及进程句柄数上限https://blog.csdn.net/chenlycly/article/details/139565038 创建GDI对象的接口比较多,要用对应的接口去释放,比如使用CreateXXXXXX创建的GDI对象,使用完后,要用DeleteObject释放;调用LoadXXXXXX函数去加载图片资源,使用完后,也要用DeleteObject释放;调用CreateXXXDC创建的DC对象,使用完后,要用DeleteDC去释放;调用GetDC获取到的DC对象,使用完后,要用ReleaseDC释放。
调用不同的接口去创建或获取GDI对象,释放时也要调用对应的释放接口,不能混淆!在这里给大家大概地罗列一下:
创建或获取GDI对象 | 删除或释放GDI对象 |
CreatePen/CreatePenIndirect(pen画笔对象)、CreateSolidBrush/CreateBrushIndirect(brush画刷对象)、CreateFont/CreateFontIndirect(Font字体对象)、CreateCompatibleBitmap(BItmap位图对象) | 对于Create出来的对象,要调用DeleteObject释放 |
CreateDC/CreateCompatibleDC(创建DC对象) | 调用DeleteDC释放 |
GetDC(获取DC对象) | 调用ReleaseDC释放 |
LoadBitmap(加载Bitmap位图) | 调用DeleteObject释放 |
LoadImage(加载图片资源) | 如果加载的是Bitmap位图,则调用DeleteObject释放; 如果加载的是Cursor光标,则调用DestroyCursor释放; 如果加载的是Icon图标,则调用DestroyIcon释放。 |
对于上面提到的创建GDI对象的API函数,在释放时该调用哪个接口,可以直接到MSDN上查看API接口的Remarks部分就会找到对应的说明。比如创建兼容位图的API函数CreateCompatibleBItmap,在Remaks部分的说明如下:
再比如加载图片的API函数LoadImage,其在Remarks部分的说明如下:
在调用Windows系统API函数遇到问题时,需要到微软MSDN帮助页面中查看API函数的详细说明(可能会给出调用函数时的注意事项,或者调用函数的示例代码等),在说明中可能会找到相关的原因!会使用MSDN,是一个Windows开发人员最基本的要求!
对于GDI对象泄漏问题的排查,首先到Windows任务管理器中看目标程序进程的GDI总数是否有异常(GDI总数特别大,好几千甚至接近10000个上限),然后再使用GDIView工具查看到底是哪一类GDI对象数量特别大:
基本可以确定该类对象有泄漏。然后去查看代码,检查每个操作该类GDI对象的地方,看看是否存在GDI对象使用完后没有释放。
使用GDIView工具查看具体是哪个GDI对象发生了泄漏。确定泄漏对象之后,需要去查看代码去排查GDI对象的泄漏点。但软件的模块多,代码量大,不好漫无目标地排查。可以尝试去找到复现问题的办法,根据复现问题的操作步骤和场景,猜测问题可能出在哪些代码块中,即缩小代码排查的范围。
关于如何使用GDIView去排查GDI对象以及项目问题排查实例,可以查看我之前写的文章:
深入探究 C++ 程序中的资源泄漏问题https://blog.csdn.net/chenlycly/article/details/133631728使用GDIView工具排查GDI对象泄漏问题(常用分析工具)
https://blog.csdn.net/chenlycly/article/details/125399896使用GDIView工具排查GDI对象泄漏导致C++程序UI界面绘制异常的问题
https://blog.csdn.net/chenlycly/article/details/140731065使用GDIView工具排查GDI对象泄漏案例的若干细节总结
https://blog.csdn.net/chenlycly/article/details/141526436
5、CreateCompatibleBitmap返回错误码8的原因及解决办法(用CreateDIBSection替换CreateCompatibleBitmap)
之前我们在加载图片去绘制窗口时(比如将图片加载起来显示到窗口中),如果图片尺寸过大,会出现CreateCompatibleBitmap返回失败,即创建位图失败的问题。调用GetLastError获取调用CreateCompatibleBitmap失败的LastError值为8,查看该错误码的含义为:
即创建位图时需要对应的内存,而内存资源不足,导致申请内存失败,所以CreateCompatibleBitmap调用失败了。创建位图的示例代码如下:
HDC hDC = ::GetDC( NULL );
HDC hMemDC = ::CreateCompatibleDC( hdc );
HBITMAP hMemBitmap = ::CreateCompatibleBitmap( hdc, nBmpWidth, nBmpHeight );
比如我们要加载的图片尺寸为3000*3000,则需要的内存大小为:
图片的宽高相乘,得到图片的像素个数,每个像素占4个字节(R、G、B、Alpha各占一个字节),则创建这样尺寸的位图需要的内存为:
3000*3000*4 = 34MB
34MB的内存很大。
调用CreateCompatibleBitmap创建是DDB(Device-dependent bitmap)设备相关位图,创建该位图使用的是系统内核的分页内存,这是稀有资源,可能会出现内存资源不够用的情况。可以使用API函数CreateDIBSection去创建DIB(Device-independent bitmap)设备无关位图,这种方式下使用的是虚拟内存,基本就会出现内存不足的问题了。关于CreateCompatibleBitmap和CreateDIBSection的详细说明,可以查看我之前写的文章:
CreateCompatibleBitmap返回错误码8的原因及解决方案(使用CreateDIBSection替换CreateCompatibleBitmap)https://blog.csdn.net/chenlycly/article/details/139586621
之前开发的截图功能,在部分机器上会频繁出现CreateCompatibleBitmap创建失败的问题,导致截图失败。后来就是用CreateDIBSection替换CreateCompatibleBitmap解决的。
使用CreateDIBSection创建位图的示例代码如下:
BITMAPINFOHEADER bmih;memset(&bmih, 0, sizeof(BITMAPINFOHEADER));bmih.biSize = sizeof(BITMAPINFOHEADER);bmih.biBitCount = 24;bmih.biCompression = BI_RGB;bmih.biPlanes = 1;bmih.biWidth = nImageWidth; // 位图的宽度bmih.biHeight = nImageHeight; // 位图的高度BITMAPINFO bmi;memset(&bmi, 0, sizeof(BITMAPINFO));bmi.bmiHeader = bmih;void* p;hBitmap = ::CreateDIBSection(cdc.GetSafeHdc(), &bmi, DIB_RGB_COLORS, &p, NULL, 0);
6、Windows开发人员必须要学会到微软MSDN上查看函数的详细说明
在调用Windows系统API函数遇到问题时,需要到微软MSDN帮助页面中查看API函数的详细说明。MSDN上可能会给出调用函数时的若干注意事项或限制条件(约束条件),或者给出调用API函数的示例代码可供参考,在函数说明中可能会找到引发问题的原因!会使用MSDN,是一个Windows开发人员基本要求!
除了去查看MSDN上的说明,在使用工具时遇到问题,可以尝试到工具的官网上查找官方的说明,比如我们有次在使用GDIView时排查GDI对象泄漏时始终无法定位问题时,就是到GDIView工具的官网上找到了问题的答案,相关问题说明可以去查看我之前写的文章:
到GDIView等工具官网上或者微软MSDN上查看文档化说明去解决问题https://blog.csdn.net/chenlycly/article/details/126004453
7、最后
使用GDI对象去编写绘图的代码相对简单,但在编码过程中要注意上面讲到的若干细节问题。
相关文章:

使用GDI对象绘制UI时需要注意的若干细节问题总结
目录 1、一个bitmap不能同时被选进两个dc中 2、CreateCompatibleDC和CreateCompatibleBitmap要使用同一个dc作为参数 3、不能删除已经被选入DC中的GDI对象 4、使用完的GDI对象,要将之释放掉,否则会导致GDI对象泄漏 5、CreateCompatibleBitmap返回错…...

51单片机(STC89C52RC版本)学习笔记(更新中...)
文章目录 参考资料1. 准备工作1.1 win10配置51单片机开发环境1.1 Ubuntu配置51单片机开发环境问题1:mcs51/8051.h依赖于mcs51/lint.h问题2:提示找不到头文件mcs51/8051.h 2. 认识51单片机2.1 STC89C52单片机2.2 管脚图2.3 原理图2.4 按键抖动2.5 头文件说…...
七:仪表盘安装-controller node
一:工具、环境准备-controller node 二:OpenStack环境准备-controller node 三:安装服务-controller node 四:工具、环境准备-compute node 五:OpenStack环境准备-compute node 六:安装服务-compute node 七…...

C++设计模式之外观模式
动机 下图中左边方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战。 如何简化外部客户程序和系统间的交互接口?如何将外部客户程序的演化和内部子系统…...
显卡(Graphics Processing Unit,GPU)比特币挖矿
1. 比特币挖矿基本原理 比特币挖矿是通过参与比特币网络的共识机制——工作量证明(Proof of Work, PoW) 来完成的。具体来说,矿工通过不断尝试不同的哈希值,以解决一个难度逐渐增大的数学问题,从而验证交易并获得比特…...

【SARL】单智能体强化学习(Single-Agent Reinforcement Learning)《纲要》
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅…...

CSS 动画效果实现:图片展示与交互
🌈个人主页:前端青山 🔥系列专栏:Css篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Css篇专栏内容:CSS 动画效果实现:图片展示与交互 前言 在现代网页设计中,动态效果能够显著…...

【机器学习】—Transformers的扩展应用:从NLP到多领域突破
好久不见!喜欢就关注吧~ 云边有个稻草人-CSDN博客 目录 引言 一、Transformer架构解析 (一)、核心组件 (二)、架构图 二、领域扩展:从NLP到更多场景 1. 自然语言处理(NLP) 2…...

Linux权限机制深度解读:系统安全的第一道防线
文章目录 前言‼️一、Linux权限的概念‼️二、Linux权限管理❕2.1 文件访问者的分类(人)❕2.2 文件类型和访问权限(事物属性)✔️1. 文件类型✔️2. 基本权限✔️3. 权限值的表示方法 ❕2.3 文件访问权限的相关设置方法✔️1. ch…...

NineData云原生智能数据管理平台新功能发布|2024年11月版
本月发布 8 项更新,其中重点发布 2 项、功能优化 6 项。 重点发布 数据库 Devops - 数据生成支持多个数据源 NineData 支持在数据库中自动生成符合特定业务场景的随机数据,用于模拟实际生产环境中的数据情况,帮助用户在不使用真实数据的情况…...
Vue中控制组件的挂载位置
在 Vue 中,append-to-body“true” 主要用于一些第三方组件(如 Element UI 或 Ant Design Vue 中的弹出框、下拉菜单等)来控制组件的挂载位置。具体来说,当你设置 append-to-body“true” 时,它会将该组件的 DOM 元素插…...
查看docker容器日志
容器里面的服务运行报错了,要查看容器的日志 要查看 Docker 容器的日志,可以使用 docker logs 命令。以下是一些常见的使用方法: 基本用法 docker logs <container_name_or_id> 查看最近的日志 docker logs --tail 100 <contai…...

Apache Commons工具类库使用整理
文章目录 Apache Commons工具类库分类- commons-lang3字符串工具:StringUtils日期工具:DateUtils数值工具:NumberUtils对象工具:ObjectUtils数组工具:ArrayUtils异常工具:ExceptionUtils枚举工具࿱…...
力扣第89题 格雷编码
题目描述 格雷编码序列是一个二进制数字序列,其中的每两个相邻的数字只有一个二进制位不同。给定一个整数 n,表示格雷编码的位数,要求返回 n 位的格雷编码序列。 示例 1 输入: n 2输出: [0, 1, 3, 2]解释&#x…...

Linux C/C++编程中的多线程编程基本概念
【图书推荐】《Linux C与C一线开发实践(第2版)》_linux c与c一线开发实践pdf-CSDN博客《Linux C与C一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com…...

解决Tomcat运行时错误:“Address localhost:1099 is already in use”
目录 背景: 过程: 报错的原因: 解决的方法: 总结: 直接结束Java.exe进程: 使用neststat -aon | findstr 1099 命令: 选择建议: 背景: 准备运行Tomcat服务器调试项目时,程序下…...
C/C++中的调用约定
在C/C编程中,调用约定(calling conventions)是一组指定如何调用函数的规则。主要在你调用代码之外的函数(例如OS API,操作系统应用程序接口)或OS调用你(如WinMain的情况)时起作用。如果编译器不知道正确的调用约定,那么你很可能会遇到非常奇怪…...

微信创建小程序码 - 数量不受限制
获取小程序码:小程序码为圆图,且不受数量限制。 目录 文档 接口地址 请求方式 功能描述 注意事项 获取 scene 值 请求参数 返回参数 对接 请求方法 获取小程序码 调用获取小程序码 总结 文档 接口地址 https://api.weixin.qq.com/wxa/get…...
springboot/ssm美食分享系统Java代码web项目美食烹饪笔记分享交流
springboot/ssm美食分享系统ava美食烹饪笔记分享交流系统web美食源码 基于springboot(可改ssm)vue项目 开发语言:Java 框架:springboot/可改ssm vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库&#…...

【Redis篇】 List 列表
在 Redis 中,List 是一种非常常见的数据类型,用于表示一个有序的字符串集合。与传统的链表结构类似,Redis 的 List 支持在两端进行高效的插入和删除操作,因此非常适合实现队列(Queue)和栈(Stack…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...

若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...