如何在C++ QT 程序中集成cef3浏览器组件去显示网页?

目录

1、问题描述

2、为什么选择cef3浏览器组件

3、cef3组件的介绍与下载

4、将cef3组件封装成sdk

5、如何使用cef3组件加载web页面

5.1、了解CefApp与CefClient

5.2、初始化与消息循环

5.3、如何创建浏览器

5.4、重载CefClient类

6、在qt客户端集成cef组件

7、最后


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(专栏文章已更新400多篇,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.htmlWindows C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html       本文讲述如何在C++ QT客户端程序中集成基于Chrome内核的浏览器组件cef3,主要用于在客户端程序中显示Web网页。

1、问题描述

       我们的qt客户端软件需要引入一个内嵌浏览器控件去显示一个Web页面,即在客户端程序中去打开某个Web网页。鉴于Chromium内核的稳定性,这个内嵌的浏览器控件决定使用Google开源的基于Chromium内核的浏览器组件cef3来实现,本文主要讲述如何在qt客户端软件中集成cef3组件。

2、为什么选择cef3浏览器组件

       如何在qt客户端中加载显示web网页,主要有两种方式:

1)使用系统自带的浏览器

启动操作系统上安装的浏览器并打开指定的web网页,此方案实现简单,不需要客户端做复杂的逻辑处理,但是受系统上安装的浏览器影响。此外,系统浏览器和客户端程序是相互独立的,没有关联性,用户体验不太好。

2)在程序中内嵌浏览器控件

直接在客户端上内嵌浏览器控件,使用该控件去打开web页面,此方式有多种技术可以实现。可以使用qt自带的组件和第三方组件等,此方式比较灵活,也可以让用户体验更好些,但是会对现有客户端代码产生一定影响。

       根据我们自身项目的特点,以及对多个技术方案的调研,整理了一下,如下所示:

经讨论,最终决定使用内嵌cef3浏览器组件的方案。

3、cef3组件的介绍与下载

      cef(Chromium Embedded Framework)是基于谷歌Chromium内核开发的框架,让开发者能够以更简单的方式使用Chromium内核开发基于网页的程序,cef3是当前维护中的版本,cef1和cef2已停止维护。cef3有多种语言的版本,包括主流的c、c++、java、python、c#等,且支持多种主流操作系统,包括windows、linux、mac os等。由于我们客户端项目是使用qt框架开发的win32版本的c++客户端,所以本案例也将使用win32下的c++版本的cef3进行介绍。

       可以到官网上去下载:

https://bitbucket.org/chromiumembedded/cef

下载压缩包并解压后,将看到一些目录,各个目录的内容如下:

cmake目录:包含cmake编译脚本。
Debug和Release目录:存放着已经编译好的cef3库文件以及运行时文件,包括dll、lib等。除了lib文件是编译时使用外,其它文件都是cef3运行时用到的文件,注意不要遗漏,否则程序可能会启动失败。
include目录:包含c接口的头文件。
libcef_dll目录:包含c++接口的头文件及其源码(cef3的c++接口是基于c接口封装的,如果想使用c++接口则需要自行编译libcef_dll目录下的源码,如果只使用c接口则直接使用include下接口就可以了。这里面还包含了一些测试代码,可手动删除)。
Resources目录:资源目录,包含cef3运行时需要使用到的资源文件。注意不要遗漏,否则程序可能会启动失败。
tests目录:包含示例代码。

4、将cef3组件封装成sdk

        实际在调研时就发现cef3组件无法直接与我们的qt-mingw版本的客户端代码一起编译(应该和cef3的交叉编译有关,即不能在windows上使用mingw的gnu编译器编译)。可以用Visual Studio(VS2008)对cef3进行一次封装并生成sdk,将生成的sdk集成进qt客户端就没问题了。

        有人可能会问,为啥不把我们的qt-mingw版本换成qt-vc++的版本呢?其实,在一开始调研时,为了方便确实是想使用此策略的,但是很快就发现了个很大的问题:由于我们qt客户端项目经过多年的迭代(包括很多代码是新人所写),导致直接将现有qt-mingw版本切换到qt-vc++版本将面临很大的改动。基于时间成本以及维护成本的考虑,先将cef3封装成sdk再集成进现有qt客户端的方案将是更有利的。

        当然,使用VS2008及其之后的版本对cef3进行封装都是可以的,这里主要考虑到我们现有客户端项目已经使用了VS2008封装的其它sdk,这样我们就可以使用同一套VC++版本的库了。本案例使用的是cef3的C++接口,在封装成sdk时也一同将C++接口的源码编译进来了,在编译C++接口的源码时有几个地方需要注意下:

1)cef3使用了c99标准头文件stdint.h,vc++2008是没有这个头文件的,需要自己额外添加此文件。vc++2008之后的版本是包含这个头文件的。
2)标准库std::min/std::max与windows头文件中的min/max宏冲突问题,这个只需要在预处理器配置中添加NOMINMAX宏即可。


       在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)

专栏1:(该精品技术专栏的订阅量已达到510多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)

C++软件调试与异常排查从入门到精通系列文章汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2:  

C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795

常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!

专栏3:(本专栏涵盖了多方面的内容,是当前重点打造的专栏,专栏文章已经更新到400多篇,持续更新中...)

C/C++实战进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。

专栏4:   

VC++常用功能开发汇总(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585

将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。

专栏5: 

Windows C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.html

根据多年C++软件开发实践,详细地总结了Windows C++ 应用软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。


5、如何使用cef3组件加载web页面

        本文因为篇幅,没法对cef3进行详细的讲解,可以看看官方的三个文档,对cef3有个基本了解:

https://bitbucket.org/chromiumembedded/cef/wiki/Tutorial.md
https://bitbucket.org/chromiumembedded/cef/wiki/Architecture.md
https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage.md

       要想使用cef3加载web,基本包含3个步骤:初始化cef3进程并启动cef3消息循环,利用cef3接口创建浏览器,使用创建好的浏览器加载web。

       根据cef3的架构理论,cef3会创建多个进程,其中主进程用于创建浏览器,进行浏览器界面的绘制等,也被称为浏览器进程(本案例中与qt客户端进程为同一进程)。其它进程为子进程,子进程包括用于web引擎渲染的渲染进程,加载诸于flash插件的插件进程,利用gpu进行加速的gpu进程。子进程由cef3内部自动创建,默认情况下主进程和子进程都是通过可执行程序创建的(也就是说qt客户端的main函数会被多次调用),可以通过配置指定子进程的可执行文件路径。

5.1、了解CefApp与CefClient

       正如前面所提到的,本案例使用的是cef3的C++接口,C++接口相较于c接口更易于使用。CefApp与CefClient是使用C++接口时需要理解的两个重要类。

       CefApp类用于处理与进程之间的交互,CefClient类用于处理与浏览器实例之间的交互。初始化cef3进程时可以指定CefApp实例,通过CefApp实例处理cef3进程的消息。创建浏览器时可以指定CefClient实例,通过CefClient实例处理浏览器的消息。

       对于cef3的C++接口,创建浏览器实例是一个异步操作,实际创建成功时需要通过CefClient实例进行通知,所以为了后续可以利用浏览器加载web,需要保存创建好的浏览器实例,这里可以对CefClient类就行重载,并在收到浏览器创建成功的通知时保存好实例。一个CefClient实例可以对应多个浏览器实例,为了容易实现对浏览器的一对一映射,本案例中每个浏览器实例在创建时都会指定一个新的CefClient实例,且在主程序中保存这些CefClient实例,并通过CefClient实例操作浏览器实例进行web加载等操作。

5.2、初始化与消息循环

       本文中使用的初始化流程如下:

cef3的初始化涉及到两个接口:CefExecuteProcess和CefInitialize:

1)CefExecuteProcess接口用于子进程的创建;

2)CefInitialize接口用于主进程的初始化。

       根据前面提到的cef3的架构理论,默认情况下主进程和子进程都是通过可执行程序创建,本案例中使用的是这种默认情况,即主进程的创建和子进程的创建都会调用qt客户端的main函数,然后在main函数里程序会调用CefSdkInit接口。这里可以通过CefExecuteProcess接口的返回值来判断当前进入的是主进程还是子进程:

  • 如果返回值小于0则表明进入的是主进程,这时程序会继续执行,并最终调用CefInitialize接口初始化主进程;
  • 如果返回值大于等于0则表明进入的是子进程,需要直接返回(如果进入的是主进程,CefExecuteProcess接口会立即返回,如果进入的是子进程,CefExecuteProcess接口会一直阻塞,直到子进程结束才返回)。

CefSdkInit的返回值是用来表明进入的是否是主进程,如果返回false则main函数应该立即返回。

       主进程在初始化时有个重要的参数需要设置:multi_threaded_message_loop,即是否使用多线程消息循环(1表示使用,0表示不使用,默认为1)。这里的设置会对后续程序的处理产生一些影响:

  • 如果选择使用多线程消息循环,则cef3内部会自动处理诸于鼠标、键盘等这种系统消息,以及一些内部消息,代价就是会造成,CefClient在处理浏览器消息通知时是在其它线程里的,和程序的主线程(本案例为客户端的界面线程)不在同一个线程。
  • 如果选择不使用多线程消息循环,则cef3内部不会主动触发对消息的处理,需要程序每隔一段时间调用一次CefDoMessageLoopWork接口,这里的难点在于多久调用一次CefDoMessageLoopWork接口比较合适,如果调用次数太频繁,造成不必要的性能浪费,如果调用次数太少,会导致cef3消息处理速度过慢,造成消息丢失或卡顿的现象(这里建议多尝试几个时间间隔,本案例中使用的是此种情况,时间间隔在10毫秒)。

5.3、如何创建浏览器

       本文中创建浏览器的接口如下:

这里可以看出,虽然本案例中提供了两套接口用于创建浏览器,实际创建浏览器调用的接口都是CefBrowserHost类的静态函数CreateBrowser,其返回值表明是否创建成功。根据CefWindwoInfo参数可以指定是创建一个独立的弹出窗口(CefSdkBrowserCreateAsPopup)还是创建一个内嵌的子窗口(CefSdkBrowserCreateAsChild)。

       CreateBrowser接口并不返回一个浏览器实例的句柄或指针啥的,真正对浏览器进行实例化的是在cef3内部进行的,等到浏览器被实例化后会通过CefClient的实例通知进来。这里的第二个参数用到的CCefSimpleClient类就是CefClient类的一个子类,本案例中每当需要创建一个浏览器实例时都会创建一个CCefSimpleClient类的实例,确保一一对应。

       在创建浏览器时会指定一个窗口句柄(windows下为HWND类型)参数,此句柄是作为浏览器窗口的父窗口句柄,不是浏览器窗口本身,cef3内部会自动创建一个新的窗口作为浏览器窗口,所以在创建浏览器时还可以指定新窗口的标题(winName)或矩形区域大小(width、height)。

5.4、重载CefClient类

       前面提到CefClient类是处理与浏览器之间的交互的,但是如果查看CefClient类的接口会发现,CefClient类本身并不直接处理与浏览器之间的消息,而是通过提供一套虚函数接口,这些接口可以创建一系列句柄类的实例,通过这些句柄类的实例再去处理相关消息。为了方便理解,这些句柄类都是类似于CefXXXHandler的形式。

        其中,CefLifeSpanHandler类就是可以处理浏览器创建成功的通知消息。鉴于cef3提供的此套接口,我们还需要对用到的CefXXXHandler类进行重载,本案例中为了实现方便,将同时从CefClient类和CefXXXHandler类继承,具体继承关系如下图所示:

所有的CefClient类接口和CefXXXHandler类接口都是虚函数接口,方便用户重载。

        当浏览器创建成功后,cef3会调用CefClient实例的GetLifeSpanHandler接口获取一个CefLifeSpanHandler实例,并调用其OnAfterCreated接口;同理当浏览器需要被销毁前会自动触发OnBeforeClose接口被调用。注意这里的OnBeforePopup接口不是在调用CefSdkBrowserCreateAsPopup(参见3.3.3节的介绍)接口创建浏览器后被调用的,而是web内部有弹出窗口时被调用(比如很多网页内部都有弹出广告等)。

       此外,CCefSimpleClient类还添加了一个CefBrowser类指针的一个成员变量。一个CefBrowser类实例代表的就是一个浏览器实例。本案例中会确保一个CefBrowser实例对应一个CCefSimpleClient实例,所以只需保存一个CefBrowser类实例的指针。在这里保存浏览器的实例方便后续加载web。自定义CCefSimpleClient类的具体实现如下图所示:

小提示:本案例中所提到的浏览器和实际我们平时使用的浏览器的概念是有所差异的,本案例中提到的浏览器的概念对应我们实际使用的浏览器的一个tab页。

6、在qt客户端集成cef组件

       本文中cef组件已经被封装成了sdk,本质上和其它sdk没有区别,集成方式也和其它sdk没有区别。这里将集成cef组件过程中发现的一些重要问题总结下。

       浏览器窗口大小缩放的问题。如果创建的是内嵌的浏览器窗口,由于浏览器窗口本身是由cef3内部创建的,qt客户端的大小在缩放时不会对浏览器窗口的大小进行缩放,这里就需要手动缩放。具体方式就是要找到对应浏览器窗口的句柄,然后调用系统函数进行缩放(win32下为MoveWindow函数)。本案例中在CefSimpleClient类中添加了一个Resize函数,如下图所示:

       浏览器窗口焦点和qt客户端窗口焦点冲突问题。也还是因为浏览器窗口是由cef3自己创建的这个原因,cef3创建的窗口不在qt系统管理范围内,所以会导致浏览器窗口和qt客户端窗口会同时获得焦点的情况,并导致某些异常问题。此问题的处理方式是在浏览器窗口获得焦点后通知qt系统。好在cef3已经为我们考虑到这个问题了,方法就是继承CefFocusHandler类,通过重载其OnGotFocus函数得知浏览器窗口什么时候会获得焦点。

       本案例中是让CefSimpleClient类同时继承了多个父类,其中就包括CefFocusHandler类。当程序得知浏览器窗口获得焦点后,简单点的方式就是触发下浏览器父类窗口(通常是某个QWidget实例)获得焦点就行了(setFocus(Qt::ActiveWindowFocusReason)),从使用者的角度来讲,浏览器父类窗口和浏览器窗口一般没有这种焦点冲突问题。

7、最后

       本文主要分享的是在qt客户端上集成cef3时遇到的一些问题的总结,没有包含很多比较详细的使用cef3的细节,有些问题也没有提及到,但是cef框架作为一个开源架构也行之有效多年,网上有很多相关的技术文章可以参考,网站下载的压缩包里也能看到一些例子。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/403870.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「12月·长沙」第三届传感、测量、通信和物联网技术国际会议(SMC-IoT 2024)

第三届传感、测量、通信和物联网技术国际会议(SMC-IoT 2024)将于2024年11月29日-2024年12月1日召开,由湖南涉外经济学院主办。会议中发表的文章将会被收录, 并于见刊后提交EI核心索引。 会议旨在围绕传感、测量、通信和物联网技术等相关研究…

基于node.js的宠物寄存管理系统,基于express的宠物寄存系统

摘 要 伴随着社会以及科学技术的发展,互联网已经渗透在人们的身边,网络慢慢的变成了人们的生活必不可少的一部分,紧接着网络飞速的发展,系统管理这一名词已不陌生,越来越多的宠物店等机构都会定制一款属于自己个性化…

DWA局部路径规划算法

DWA——Dynamic Window Approach动态窗口法 发展 动态窗口法是一种局部路径规划算法,起源于对移动机器人在复杂环境中实时避障的需求。该算法由F. D. Proentzen和O. Khatib提出,后经过不断优化,已成为移动机器人领域中的标准算法之一。 运…

xss.function靶场(hard)

文章目录 WW3源码分析源码 DOMPpurify框架绕过覆盖变量notifyjs作用域和作用链域构建payload WW3 源码 <!-- Challenge --> <div><h4>Meme Code</h4><textarea class"form-control" id"meme-code" rows"4"><…

Spring Boot实战:使用模板方法模式优化数据处理流程

概述 在软件开发过程中&#xff0c;我们经常需要处理各种各样的数据&#xff0c;这些数据可能来自不同的源&#xff0c;比如数据库、文件系统或者外部API等。尽管数据来源不同&#xff0c;但很多情况下处理这些数据的步骤是相似的&#xff1a;读取数据、清洗数据、转换数据格式…

华为的流程管理

华为建设流程体系始于2000年&#xff0c;那时华为公司面临着快速扩张和全球化发展的挑战&#xff0c;意识到传统的管理模式已经无法满足业务发展的需求。为了提高公司的管理效率和竞争优势&#xff0c;华为决定启动流程体系的建设。在建设过程中&#xff0c;华为借鉴了业界最佳…

云计算的三大服务模式:IaaS、PaaS、SaaS的深入解析

在数字化转型的浪潮中&#xff0c;云计算以其独特的灵活性、可扩展性和成本效益&#xff0c;正逐渐成为企业IT架构的核心。云计算提供了三种主要的服务模式&#xff0c;分别是基础设施即服务&#xff08;IaaS&#xff09;、平台即服务&#xff08;PaaS&#xff09;和软件即服务…

Spring发送邮件性能优化?如何集成发邮件?

Spring发送邮件安全性探讨&#xff01;Spring发送邮件功能有哪些&#xff1f; 邮件发送的性能逐渐成为影响用户体验的重要因素之一。AokSend将探讨如何在Spring框架中进行Spring发送邮件的性能优化&#xff0c;确保系统能够高效、稳定地处理大量邮件请求。 Spring发送邮件&am…

和鲸携手山东大学数字人文实验室,推动新文科与人工智能融合发展

为深入推进产教融合与校企合作&#xff0c;推动人工智能在人文学科中的广泛应用与深入发展&#xff0c;8 月 15 日&#xff0c;山东大学数字人文实验室与和鲸科技 101 计划推进会暨新文科人工智能实验室标杆案例打造讨论会于威海顺利召开。山东大学数字人文实验室副主任陈建红、…

12.2 使用prometheus-sdk向pushgateway打点

本节重点介绍 : 使用golang sdk打prometheus4种指标&#xff0c;推送到pushgateway gauge、counter、histogram、summary的初始化4种类似的设置值的方法推送到pushgateway的方法 prometheus配置采集pushgateway&#xff0c;grafana上配大盘 golang-sdk 项目地址 https://git…

系统架构设计师 - 软件工程(2)

软件工程 软件工程&#xff08;13-22分&#xff09;非常重要软件系统建模系统设计界面设计 ★★软件设计结构化设计 ★★面向对象设计 ★★★★★基本过程设计原则设计模式创建型模式&#xff1a;创建对象结构型模式&#xff1a;更大的结构行为型模式&#xff1a;交互及职责分配…

科三预约考试,为什么我场次排名在前,后面排名又变了

什么时候知道是否预约成功 系统确认考试预约结果的时间一般为考试前5-7个工作日&#xff0c;同时根据预约人数系统会自行判断提前1-2日或延长1-2日公示预约结果&#xff0c;学员至少考试前三天会收到预约成功短信通知。 如果预约失败了怎么办&#xff1f;会计入考试次数吗&am…

Java之线程篇一

目录 如何理解进程&#xff1f; 进程和线程的区别 线程的优点 线程的缺点 线程异常 线程用途 创建线程 方法一&#xff1a;继承Thread类&#xff0c;重写run() 观察线程 小结 方法二&#xff1a; 实现Runnable接口&#xff0c;重写run() 方法三&#xff1a;继承Threa…

【西安电子科技大学】2024年士兵计划考研信息总结!

西安电子科技大学 学校简介上方图片奖助学金下方图片研招网址https://gr.xidian.edu.cn/普通复试https://gr.xidian.edu.cn/info/1073/13301.htm士兵复试总分为各学科门类、各专业学位类别&#xff08;领域&#xff09;国家A类线&#xff0c;单科不限。士兵名额20报考说明无录取…

MES系统从哪几方面提升企业制造水平?

在当今这个快速变化的制造环境中&#xff0c;企业对于提升制造水平的追求从未停止。制造执行系统&#xff08;MES&#xff09;作为连接企业战略规划与车间实际操作的核心工具&#xff0c;其重要性日益凸显。盘古信息MES系统&#xff0c;凭借其独特的功能模块和创新的设计理念&a…

两种图像透明背景转特定颜色方法的比较

之前写过一篇博客&#xff0c;关于透明背景转换为特定颜色&#xff0c;当时使用了NumPy数组采用布尔索引转换的方式&#xff0c;这次我们把这种转换和常规的逐像素转换的方式进行比较&#xff0c;看那种方法效率更高。记得以前使用Matlab的时候&#xff0c;显然是矩阵布尔索引的…

基于SSM的体育馆预约管理系统---附源码84196

摘 要 体育馆作为一个重要的运动场所&#xff0c;需要进行预约管理以保证资源的合理利用和场馆秩序的维护。传统的人工预约管理方式存在效率低、容易出错等问题&#xff0c;因此&#xff0c;在互联网高速发展的当下&#xff0c;需要设计和实现一个基于SSM的体育馆预约管理系统&…

优思学院|六西格玛实施关键:如何整合定性与定量数据

在精益六西格玛的世界中&#xff0c;数据不仅是工具&#xff0c;更是推动变革和改进的关键力量。了解定性数据和定量数据的区别&#xff0c;可以为流程改进提供强大的见解和策略。 定性数据与定量数据的本质 首先&#xff0c;定性数据和定量数据是两种截然不同的概念。定性数据…

springboot+vue 初始

1.控制器 2.文件上传拦截器 #过滤规则 # 默认访问static下面的文件http://localhost:8009/4.jpeg&#xff0c; # 带上static-path-pattern/static/**后&#xff0c;http://localhost:8009/static/4.jpeg spring.mvc.static-path-pattern/static/**#静态资源位置 spring.web.res…

笔记分享: 香港中文大学CSCI5610高级数据结构——最邻近查询

文章目录 Approximate Nearest Neighbor Search \textbf{Approximate Nearest Neighbor Search} Approximate Nearest Neighbor Search 1. Doubling Dimension \textbf{1. Doubling Dimension} 1. Doubling Dimension 1.0. Intro \textbf{1.0. Intro} 1.0. Intro 1.1. Doubling…