当前位置: 首页 > news >正文

【Spiffo】光速项目:LVGL v9框架下的MIPI简易相机_Part2

简介

本期接上回的工程部署讲一下整个工程的框架逻辑以及相关的模块作用机制,包括mipi抓图像以及后续传递到显示屏的链路逻辑等。

一、核心逻辑

1、如何抓到图像数据并显示

首先能够从摄像头捕获画面并显示是一个相机最起码要能实现的功能。所以先要搞清楚整个链路的大致逻辑。

(1)Linux下的设备驱动系统的控制逻辑

绝大部分情况下,在Linux下对设备的控制,可以用“修改结构体参数,然后提交修改”完成,后面驱动会讲为什么,这里先记住这个原则。举几个例子:

设备V4L2Frame bufferDRM(GPUALSA(音频相关
设备节点/dev/video*/dev/fb*/dev/dri/card*/dev/snd/*
主要结构体(太多,不完全列举v4l2_format,v4l2_controlfb_var_screeninfodrm_mode_modeinfsnd_ctl_elem_value
/* ----------------------------------V4L2 举例-------------------------------*/
struct v4l2_format fmt = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,.fmt.pix = { .width = 1920, .height = 1080, .pixelformat = V4L2_PIX_FMT_YUYV },
}; //设置参数ioctl(fd, VIDIOC_S_FMT, &fmt); // 提交/*--------------------------------Framebuffer 举例---------------------------*/
struct fb_var_screeninfo var = {.xres = 1024;.yres = 768;.bits_per_pixel = 32;
}; //设置参数ioctl(fd, FBIOGET_VSCREENINFO, &var);// 提交/*---------------------------------DRM 举例---------------------------------*/
struct drm_mode_modeinfo mode = {.hdisplay = 1920,.vdisplay = 1080,.clock = 148500,}; //设置参数drmModeSetCrtc(fd, crtc_id, buffer_id, 0, 0, &connector_id, 1, &mode); // 提交

可以看到,这些设备都是通过修改相关结构体参数,然后通过ioctl(或类似函数)递交进行相关的修改,从而达到控制设备的效果。

本次工程用的v4l2以及framebuffer都是通过ioctl进行参数提交的,所以再说一下ioctl的函数原型:

int ioctl(int fd, unsigned long request, ... /* void *arg */);
  • - fd,调用open函数打开设备时获取的文件描述符(相当于一个设备的编号
  • - request,控制的指令,一般来说已经进行了相关的宏定义,网上一查就有
  • - arg, 可选参数,一般来说就是上面编辑完以后的结构体的指针

(2)设备参数设置

在了解了上述机制以后,想要控制相应的设备,就该先去找相关的存储属性的结构体并找到递交参数的API函数,这里直接给出:

V4L2:

相当于水源源不断流过来,你有count数量的桶,接满一桶就提走倒进容器里,往复循环。

Framebuffer:

最终设置里就可以写为:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <linux/types.h>    
#include <linux/videodev2.h>
#include <linux/fb.h>
#include "convertor.h"#define   WIDTH   800                       
#define   HEIGHT  480                       
#define   FMT     V4L2_PIX_FMT_YUYV         
#define   COUNT   4                         
#define CLAMP(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))int main(int argc, char **argv)
{	unsigned char *buffer_datas[COUNT];            int ret;int v4l2_fd;uint8_t rgb_data[800 * 480 * 3];/*---------------------frame buffer初始化-------------------*/// open -> 编辑结构体 -> 提交修改int fb_fd = open("/dev/fb0", O_RDWR);struct fb_var_screeninfo vinfo;  //这里仅作演示,就不多调了,默认就可以用,只是不调整格式看起来会怪怪的ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo); //直接提交//图像存储变量,待会用来装摄像头送来的数据流size_t fb_size = vinfo.yres_virtual * vinfo.xres_virtual * (vinfo.bits_per_pixel / 8);uint16_t *fb_mem = (uint16_t *)mmap(0, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);/*---------------------V4L2初始化-------------------*/// open -> 编辑结构体 -> 提交修改v4l2_fd = open("/dev/video0", O_RDWR);       //设置v4l2_froamt  设置结构体 -> 提交struct v4l2_format format;format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  format.fmt.pix.width = WIDTH;               format.fmt.pix.height = HEIGHT;             format.fmt.pix.pixelformat = FMT;          ret = ioctl(v4l2_fd, VIDIOC_S_FMT, &format);   //提交//设置v4l2_requestbuffers  设置结构体 -> 提交struct v4l2_requestbuffers reqbuf;reqbuf.count = COUNT;                       reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  reqbuf.memory = V4L2_MEMORY_MMAP;           ret = ioctl(v4l2_fd, VIDIOC_REQBUFS, &reqbuf); //提交//设置v4l2_buffer  设置结构体 -> 提交 ,//这里因为需要四个buffer来轮流装填,所以用了个for循环,直接执行四次也行,比较憨罢了struct v4l2_buffer buff;buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buff.memory = V4L2_MEMORY_MMAP;for (int i = 0; i < COUNT; i++){buff.index = i;ret = ioctl(v4l2_fd, VIDIOC_QUERYBUF, &buff);ret = ioctl(v4l2_fd, VIDIOC_QBUF, &buff);    //实际上就是图上画的轮流工作的四个bufferbuffer_datas[i] = mmap(NULL, buff.length, PROT_READ, MAP_SHARED, v4l2_fd, buff.m.offset);}//启动流int on = V4L2_BUF_TYPE_VIDEO_CAPTURE;       ret = ioctl(v4l2_fd, VIDIOC_STREAMON, &on);     while(1){memset(&buff, 0, sizeof(buff));buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buff.memory = V4L2_MEMORY_MMAP;ret = ioctl(v4l2_fd, VIDIOC_DQBUF, &buff);  //把接满的buffer拿出来Convert_YUYV_To_RGB565(buffer_datas[buff.index], fb_mem, WIDTH, HEIGHT); //把数据倒出ret = ioctl(v4l2_fd, VIDIOC_QBUF, &buff); //把空容器放回去}for (int i = 0; i < COUNT; i++){buff.index = i;munmap(buffer_datas, buff.length);     	}                         close(v4l2_fd);munmap(fb_mem, fb_size);close(fb_fd);return 0;
}//底下是我做的其他后处理,等一下会讲,看上面就行
void Convert_YUYV_To_RGB888(uint8_t y, uint8_t u, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b){int C = y;int D = u - 128;int E = v - 128;*r = CLAMP(C + 1.402 * E);*g = CLAMP(C - 0.344136 * D - 0.714136 * E);*b = CLAMP(C + 1.772 * D);}uint16_t Convert_RGB888_To_RGB565(uint8_t r, uint8_t g, uint8_t b){return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}void Convert_YUYV_To_RGB565(uint8_t *ptr,uint16_t *fb_mem, int width , int height){uint8_t Y0;uint8_t U ;uint8_t Y1;uint8_t V ;uint8_t R0, G0, B0, R1, G1, B1;for(int i=0; i < width * height; i +=2){Y0 = ptr[0];U  = ptr[1];Y1 = ptr[2];V  = ptr[3];Convert_YUYV_To_RGB888(Y0, U, V, &R0, &G0, &B0);Convert_YUYV_To_RGB888(Y1, U, V, &R1, &G1, &B1);fb_mem[i] = Convert_RGB888_To_RGB565(R0, G0, B0);  //数组名实际上就是指针等价于 &()fb_mem[i + 1] = Convert_RGB888_To_RGB565(R1, G1, B1);ptr += 4;}}

可以编译运行一下,不出意外的话结果长这样,摄像头的流数据直接流向framebuffer:

2、格式转换

当然了,摄像头直接输出的数据是.raw格式或是.YUYV格式的原生数据,所以还不能直接使用,需要进行一轮格式转换,一般来说这个步骤可以交给编码器完成,这样更快,不过可迁移性就弱了,所以这里使用软转换。

假设使用软转换的话,就需要知道你的源格式长什么样,目标格式长什么样,这些信息都可以网上找到。比如说在这个demo里,我摄像头设置的YUYV422格式,我的屏支持RGB565(部署的时候没说是因为这两种基本都支持,没有修改的必要,假设你需要的是H.264或其他,就需要进行相应的修改了),转换如下:

即:

对应了上述demo的这里,具体函数定义可以看convertor.c

3、嵌入LVGL框架

在了解了如何将摄像头数据传送到屏幕并显示后,接下来的问题就在于如何将二者嵌入到LVGL的框架中,实际上思路也很简单,只要找到LVGL提供的众多API中能够作为其数据载体的即可,并非只有一种方案,这里只是其中一种实现方式。

摄像头数据方面,因为LVGL并不占用系统的摄像头资源,因此直接将上面的demo搬运进lvgl的初始化阶段即可;而framebuffer则被LVGL占用,需要将二者的程序逻辑进行整合,下面简要说明LVGL的刷屏机制:

LVGL中所有的元件都存在一个“占地面积”的属性,静态内容出现buffer的修改则进行刷屏,动态内容不受前者影响独立刷屏,刷新区域仅限该元件脚下的占地。那么将摄像头画面嵌入LVGL显示界面的两种思路即为:不断刷新静态内容或设置一系列buffer串轮询播放

  • - 不断刷新静态内容:不断激活图像组件或类似组件进行刷新,好处在于实时性较强,摄像头画面能够在最短时间刷新出来;但是坏处在于系统负担很重,操作实时性变弱
  • - 设置buffer序列循环播放:使用canvas或者动画组件填充其内存区域进行播放,好处在于独立于操作,实时性较强;坏处在于显示的画面并不等于摄像头当前的画面,动态时存在一定的粘滞感(不跟手)。同时,如果填充和LVGL读取的正好是一个缓冲区,则会出现轻微的画面撕裂(需要引入双buffer进行一次处理)。
  • - 当然,上述两种依赖于LVGL框架内的实现方法,在画面刷新率上都不及上一节demo的实现,追求极致的性能应该使用QT的实现方案,剔除多余的程序逻辑。

上篇程序使用的是第二种方案,因为粘滞感和画面撕裂的解决要比解决系统负载过高来的容易,基本思路是利用LVGL自带的动画框架。和gif图的播放类似,LVGL的动画框架的逻辑就是,使用一系列的buffer串,每个buffer存储一帧画面,从头播到尾,然后再次回到头部,往复循环(实际上序列里只有一帧也行,原地刷新,更快,但是撕裂程度也水涨船高):

详细的说明参见LVGL官方:

https://docs.lvgl.io/master/details/main-modules/animation.html

那么此时,原来demo中摄像头画面数据输入到frame buffer的操作现在就改成了将其放进图中的lv_image_dec_t帧描述结构体中,剩下的就交给LVGL框架处理了。

二、程序框架

了解了相关核心逻辑后,不难得出系统框架为:

1、画面延迟问题

当然,原生的框架下直接用会有之前提到的迟滞感问题,这是因为每一轮循环都会顺序处理所有的动效和逻辑,这就导致了画面送入程序后至少还需要等待一整个循环的时间才能显示到屏幕上。要想解决这个问题,可以使用多线程的方法。

所谓多线程,就是将其从原来的一个大循环拆分成多个小循环,每个小循环执行一小段时间,交替进行,如图:

这就意味着,画面不需要等待完整的循环周期才开始显示,而是拆分成若干个小份一点点显示出来,能够有效解决延迟问题。

2、画面撕裂问题

另外,之前提到我采用的方法的弊端里还有一个画面撕裂的问题,关于这里的处理,再多引一组buffer出来作为中间的缓冲,避免LVGL读取数组的时候数组遭到改动即可。也许是因为树莓派性能本身比较强,这个问题没有造成严重的观感影响,我就没有多此一举了。假设是使用主频不太高的MPU进行实践,也许会出现上述问题,可以按照这个方法解决一下。

总结

到这里,整个程序的框架就讲清楚了,剩下的诸如界面控件之类的就和老版本的LVGL没什么区别,官方的文档里也有很详细的说明,这里就不再赘述(如果需要讲的话也可以留言,没有的话下次讲驱动了)。

相关文章:

【Spiffo】光速项目:LVGL v9框架下的MIPI简易相机_Part2

简介 本期接上回的工程部署讲一下整个工程的框架逻辑以及相关的模块作用机制&#xff0c;包括mipi抓图像以及后续传递到显示屏的链路逻辑等。 一、核心逻辑 1、如何抓到图像数据并显示 首先能够从摄像头捕获画面并显示是一个相机最起码要能实现的功能。所以先要搞清楚整个链…...

pycharm编译部署智能合约(solcx与web3搭配)

solcx 是一个 python 库,提供了 solidity 编译器的 python 绑定。它使开发者能够直接从 python 中编译 solidity 源代码,生成以太坊智能合约的字节码(Bytecode)和 ABI(Application Binary Interface)。这个库通常用于与 Web3 库配合使用,帮助开发者进行智能合约的部署、…...

微信小程序中的openid的作用

微信小程序中的openid的作用 引言 在当今数字化时代&#xff0c;用户体验成为了产品成功与否的关键因素之一。微信小程序作为连接用户与服务的重要桥梁&#xff0c;在提升用户体验方面发挥着重要作用。其中&#xff0c; openid&#xff08;开放身份标识符&#xff09;是微信小…...

AAAI 2025新研究!大语言模型+MARL=论文新思路?

最新研究显示&#xff0c;多智能体强化学习&#xff08;MARL&#xff09;正迎来一系列技术革新&#xff0c;让AI系统真正具备“群体智能”。同济大学团队提出的动态图通信网络&#xff08;TGCNet&#xff09;&#xff0c;通过Transformer建模智能体间的动态协作关系&#xff0c…...

旅行世界宠物养殖合成游戏源码

旅行世界宠物养殖合成游戏源码&#xff0c;游戏养成类系统&#xff0c;用户能够通过养狗和参加其他活动获取算力&#xff0c;每日任务不断更新&#xff0c;完结即可收取算力&#xff0c;算力能够兑换现金红包。 邀请好友得两级活跃收益提成&#xff0c;徒弟B100.%&#xff0c;徒…...

列表之链表_C

数据结构&#xff08;邓俊辉&#xff09;&#xff1a;列表及相关概念_listnodeposi-CSDN博客 #include <stdio.h> #include <stdlib.h>// 定义Rank类型为int typedef int Rank;// 定义ListNode结构体 typedef struct ListNode {int data;struct ListNode* pred;st…...

图解Java设计模式

1、设计模式面试题 2、设计模式的重要性 3、7大设计原则介绍...

CCF GESP Python编程 四级认证真题 2025年3月

Python 四级 2025 年 03 月 题号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 答案 D C B C D C A A D B D A C B C 1 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09; 第 1 题 2025年春节有两件轰动全球的事件&#xff0c;一个是DeepSeek横空出世&#xff0c;另一个是…...

2025最新系统 Git 教程(四)

2.6 Git 基础 - 打标签 打标签 像其他版本控制系统&#xff08;VCS&#xff09;一样&#xff0c;Git 可以给仓库历史中的某一个提交打上标签&#xff0c;以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点&#xff08; v1.0 、 v2.0 等等&#xff09;。 在本节中…...

数学知识——欧拉函数

欧拉函数 1 ∼ N 1∼N 1∼N 中与 N N N互质的数的个数被称为欧拉函数&#xff0c;记为 ϕ ( N ) \phi(N) ϕ(N)。 欧拉函数 对于 N p 1 α 1 p 2 α 2 p 3 α 3 . . . p k α k Np_1^{\alpha_1}p_2^{\alpha_2}p_3^{\alpha_3}...p_k^{\alpha_k} Np1α1​​p2α2​​p3α3​​…...

Dify 识别 “subject“ and “intention“ 的提示词

Dify 识别 "subject" and "intention" 的提示词 内容如下&#xff1a; You need to decompose the users input into "subject" and "intention" in order to accurately figure out what the users input language actually is. Not…...

Hi168云平台部署Ansible学习环境

前言 之前发布的文章已经介绍过了在Hi168云平台部署openEuler学习环境&#xff0c;那么既然能部署openEuler了&#xff0c;其他的各类学习环境自然也就可以部署了。 Ansible简介 Ansible 是一个运维自动化工具&#xff0c;可以通过 SSH 协议对远程主机进行管理&#xff0c;对…...

Anacond虚拟环境里安装GPU版本Pytorch

CUDA/cudnn/CUDAToolkit简单区分 pytorch与cuda关系简单介绍 pytorch是一个深度学习的框架&#xff0c;能够调用cuda进行gpu加速。一般来说你的电脑里是有相关cuda的驱动的&#xff08;可用nvidia-smi命令验证&#xff0c;能运行就说明有&#xff0c;不能运行去搜索安装&#…...

FRP的proxies只是建立通道,相当于建立与服务器沟通的不同通道而不是直接将路由器与服务器云端沟通

没有更好的办法了吗&#xff0c;我看frpc.toml的里面可以设置两个proxies那我esp32的监听端口设置在frpc.toml里面它不也能跟云服务器建立联系吗&#xff0c;比如远程与本地端口都配置为5112那云服务器接收到的5112访问会以frp配置的本地端口5112转发到frp客户端的路由器&#…...

Android开发鸿蒙环境问题记录

Android开发鸿蒙环境问题记录 &#xff08;用于记录开发中鸿蒙环境差异及问题&#xff0c;持续更新&#xff09; 2025.4.9 问题 使用android.intent.action.TIME_TICK广播时&#xff0c;动态注册在鸿蒙4.0系统正常&#xff0c;但在鸿蒙3.0系统无法接收广播。 解决方案 在An…...

在 WSL2的 Ubuntu 20.04 中安装 Docker

WSL1升级到WSL2参考&#xff1a;WSL1升级到WSL2注意事项-CSDN博客 1. 更新系统包 首先&#xff0c;确保系统包是最新的&#xff1a; sudo apt update sudo apt upgrade -y sudo apt upgrade -y 是 Ubuntu/Debian Linux 系统中的一条命令&#xff0c;用于升级所有已安装的软…...

LeetCode 252 会议室题全解析:Swift 实现 + 场景还原

文章目录 摘要描述题解答案题解代码分析示例测试及结果时间复杂度空间复杂度总结 摘要 在这篇文章中&#xff0c;我们将深入探讨LeetCode第252题“会议室”的问题&#xff0c;提供一个用Swift编写的解决方案&#xff0c;并结合实际场景进行分析。通过这篇文章&#xff0c;你将…...

Postman的内网使用教程

在软件开发和测试过程中&#xff0c;接口测试是确保系统间通信正常的重要环节。当处于内网环境&#xff0c;无法直接访问外网资源时&#xff0c;如何高效地使用Postman进行接口测试也逐渐成为许多开发者关心的问题。 前期准备 安装Postman 从官方网站下载并安装最新版本的Pos…...

【软件测试】Postman中如何搭建Mock服务

在 Postman 中&#xff0c;Mock 服务是一项非常有用的功能&#xff0c;允许你在没有实际后端服务器的情况下模拟 API 响应。通过创建 Mock 服务&#xff0c;你可以在开发阶段或测试中模拟 API 的行为&#xff0c;帮助团队成员进行前端开发、API 测试和集成测试等工作。 Mock 服…...

【NLP 57、LLM通用能力评价方式】

人生如题&#xff0c;放下&#xff0c;是最优雅的解法 —— 25.4.9 目前&#xff0c;我们通过一些特殊的“集合”来评价大语言模型效果 一、MMLU 集合 测量大规模多任务语言理解 评估模型在57个学科领域的综合知识理解能力&#xff0c;覆盖人文、社科、STEM&…...

centos7.9升级OpenSSL 1.1.1

centos7.9升级openssl 人工智能已经很准了&#xff1a; 问题&#xff1a; [rootcentos01 ~]# openssl version OpenSSL 1.0.2k-fips 26 Jan 2017 [rootcentos01 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) 需要升级OpenSSL&#xff0c;请给出具体…...

10A 大电流 DCDC 降流芯片 WD5030

10A 大电流 DCDC 降压芯片 WD5030 在电子设备的电源管理领域&#xff0c;高效稳定的 DCDC 芯片至关重要。今天我们来深入探讨一款性能卓越的 10A 大电流 DCDC 降流芯片 ——WD5030。它在众多电子应用场景中展现出了强大的优势&#xff0c;为各类设备的稳定供电提供了可靠保障。…...

# 基于BERT的文本分类

基于BERT的文本分类项目的实现 一、项目背景 该文本分类项目主要是情感分析&#xff0c;二分类问题&#xff0c;以下是大致流程及部分代码示例&#xff1a; 二、数据集介绍 2.1 数据集基本信息 数据集自定义类型二分类&#xff08;正面/负面&#xff09;样本量训练集 验证…...

Verilog学习-1.模块的结构

module aoi(a,b,c,d,f);/*模块名为aoi&#xff0c;端口列表a、b、c、d、f*/ input a,b,c,d;/*模块的输入端口为a,b,c,d*/ output f;;/*模块的输出端口为f*/ wire a,b,c,d,f;/*定义信号的数据类型*/ assign f~((a&b)|(~(c&d)));/*逻辑功能描述*/ endmoduleveirlog hdl 程…...

界面控件DevExpress WPF v25.1新功能预览 - 数据网格、报表性能增强

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...

【创新实训个人博客】prompt嵌入

通过对camel技术的理解&#xff0c;修改了项目内容 能够初步实现广告内容相关的文本 修改了typing.py中的定义 class RoleType(Enum): ASSISTANT "assistant" USER "user" CRITIC "critic" EMBODIMENT "embodiment" DEFAULT &q…...

Linux 进程的替换

进程程序替换 要讲好这个我为大家准备了五个步骤 1. 先用代码给大家展示一下现象 2.解释原理 3.将代码改成多进程版 4.使用所有的方法&#xff0c;并认识函数参数的含义。 5.其他 我们现在开始第一个 1. 先用代码给大家展示一下现象 关于进程的替换一共有七个函数&…...

netty启用websocket的压缩机制

netty启用websocket的压缩机制 package com.aerotop.connector.websocket.base;import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.compression.JZlibDec…...

【python】针对Selenium中弹框信息无法定位的问题,以下是综合解决方案及注意事项:

一、常见原因分析 1.1 弹窗类型不匹配 若弹窗为alert&#xff0c;需使用driver.switch_to.alert处理&#xff1b; 若为confirm或prompt&#xff0c;同样适用该方法。 1.2 窗口句柄切换问题 新窗口或弹窗可能开启新句柄&#xff0c;需先通过driver.window_handles切换到对应句…...

进程与信号

前言 接触计算机的时候我们就接触过信号。比如说当我们进程卡死的时候&#xff0c;windows系统会跳出来一个弹窗告诉我们是否等待进程响应&#xff0c;如果关闭进程那么系统就会发信号给进程然后终止掉它。再比如我们打开任务管理器的时候&#xff0c;想要关闭进程那也是在发送…...

SQL解析器:实现进阶功能

SQL解析器&#xff1a;实现进阶功能 在上一篇文章中&#xff0c;我们介绍了SQL解析器的基础架构和核心功能实现&#xff0c;包括基本的SELECT、INSERT、UPDATE语句解析。本文将深入探讨SQL解析器的进阶功能实现&#xff0c;重点关注我们新增的DROP、JOIN、DELETE语句解析以及嵌…...

字体从版权合规到技术适配,你好字库全场景解决方案解析

一、开发者字体使用的三大核心困境 在软件开发与设计过程中&#xff0c;字体选择往往成为「甜蜜的负担」&#xff1a; 版权风险高&#xff1a;商业项目误用未授权字体&#xff0c;可能面临数万元赔偿&#xff08;某创业公司曾因使用「方正粗黑」被索赔 8 万元&#xff09; …...

深入理解 Java ArrayList 扩缩容机制(含源码分析)

标签&#xff1a; Java, ArrayList, 集合框架, 源码分析, 扩容机制, 性能优化, CSDN 摘要&#xff1a; java.util.ArrayList 作为 Java 集合框架中最常用的类之一&#xff0c;其动态数组的特性深受开发者喜爱。然而&#xff0c;“动态”背后的扩容与缩容机制是怎样的&#xff…...

LeetCode详解之如何一步步优化到最佳解法:26. 删除有序数组中的重复项

LeetCode详解系列的总目录&#xff08;持续更新中&#xff09;&#xff1a; LeetCode详解之如何一步步优化到最佳解法&#xff1a;前100题目录&#xff08;更新中...&#xff09;-CSDN博客 LeetCode详解系列的上一题链接&#xff1a; LeetCode详解之如何一步步优化到最佳解法…...

doris基础使用

目录 1、一般使用 2、数据源通过catalog连接 1、es 2、clickhouse 3、db2 3、问题 &#xff08;1&#xff09;doris连接es一直报错 1、一般使用 &#xff08;1&#xff09;查询doris的catalog show catalogs; &#xff08;2&#xff09;查询catlog的连接信息 以catalog…...

Python 3.x cxfreeze打包exe教程

Python 3.x cxfreeze打包exe教程 https://blog.csdn.net/qq_33704787/article/details/123926953 去官网 下载安装 pip install cx-Freeze7.2.9 https://pypi.org/project/cx-Freeze/7.2.9/ 安装到 你的 python 的 script文件夹下面 &#xff08;全局或是 虚拟环境都行&#x…...

SQL开发的智能助手:通义灵码在IntelliJ IDEA中的应用

SQL 是一种至关重要的数据库操作语言&#xff0c;尽管其语法与通用编程语言有所不同&#xff0c;但因其在众多应用中的广泛使用&#xff0c;大多数程序员都具备一定的 SQL 编写能力。然而&#xff0c;当面对复杂的 SQL 语句或优化需求时&#xff0c;往往需要专业数据库开发工程…...

nginx或tengine服务器,配置HTTPS下使用WebSocket的线上环境实践!

问题描述&#xff1a; HTTPS 下发起WS连接&#xff0c;连接失败&#xff0c;Chrom 浏览器报错。 socket.js:19 Mixed Content: The page at https://app.XXX.com was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint ws://172.16.10.80:903…...

原创工具scoopex - scoop增强工具,提供github proxy和url净化功能

说明 scoop是一款十分优秀的windows下软件管理工具&#xff0c;但是在国内使用&#xff0c;总会遇到网络问题&#xff0c;不得不翻墙或者梯子才能解决。 网上有很多提供了cn版本的bucket&#xff0c;虽然解决了一些问题&#xff0c;但是也带来了默认proxy不可用问题&#xff0…...

TPS入门DAY03 服务器篇

1.创建按钮和对应的回调函数 /* 大厅按钮 */UPROPERTY(meta (BindWidget))UButton* HostButton;/* 加入会话按钮 */UPROPERTY(meta (BindWidget))UButton* JoinButton;private:UFUNCTION()void OnHostButtonClicked();UFUNCTION()void OnJoinButtonClicked(); 创建调试助手 …...

STM32单片机入门学习——第30节: [9-6] FlyMcu串口下载STLINK Utility

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.09 STM32开发板学习——第30节: [9-6] FlyMcu串口下载&STLINK Utility 前言开发…...

基于springboot钻孔数据管理系统的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本钻孔数据管理系统采用B/S架构&#xff0c;数据库是MySQL&#xff0c;网站的搭建与开发采用了先进的Java语言、Hadoop、数据可视化技术进行编写&#xff0c;使用了Spring Boot框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。用户主要功能包括&…...

asp.net core 项目发布到 IIS 服务器

目录 一、VS2022 发布 二、设置IIS服务 三、配置IIS管理器 &#xff08;一&#xff09;打开IIS管理器 &#xff08;二&#xff09;添加站台 &#xff08;三&#xff09;配置应用程式集区 四、安装ASP.NET Core Hosting Bundle 五、设定IIS的日志位置 六、测试 一、VS2…...

自动化 Markdown 图片上传到 GitHub

自动化 Markdown 图片上传到 GitHub 1. 代码介绍 本代码用于自动扫描指定目录下的 Markdown 文章&#xff0c;提取其中的本地图片&#xff0c;并上传到 GitHub 仓库&#xff0c;最后替换文章中的图片路径&#xff0c;实现图片的托管和访问加速。 2. 主要功能 读取本地配置文…...

Java中23种设计模式之代理模式

一、什么是代理模式&#xff1f; 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;其核心思想是&#xff1a; 通过引入一个代理对象作为中间层&#xff0c;控制对目标对象&#xff08;真实对象&#xff09;的访问&#xff0c;并在访问前后添加…...

git单独跟踪远程分支及处理合并异常情况

在 Git 中&#xff0c;自动跟踪远程分支&#xff08;Tracking Remote Branch&#xff09;是指&#xff1a; 当你创建一个本地分支时&#xff0c;让它直接关联&#xff08;绑定&#xff09;到对应的远程分支。这样&#xff0c;后续的 git pull、git push 等操作可以省略参数&…...

口腔助手|口腔挂号预约小程序|基于微信小程序的口腔门诊预约系统的设计与实现(源码+数据库+文档)

口腔小程序 目录 基于微信小程序的口腔门诊预约系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、小程序前台界面实现 2、后台管理员模块实现 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、论文参考 七、最新计算…...

Windows本地账户后门被关,微软强制使用在线账户

初次接触Windows10或者Windows11的同学应该都被微软一开始激活注册的在线账户坑过吧。 一切都按照微软的正向指引激活步骤&#xff0c;但到了账户注册的步骤时&#xff0c;不明所以的小白会按照微软的步骤进行新注册账户。 但坑就在这里&#xff0c;由于微软的账户服务器在国外…...

分类算法的介绍和应用场景

分类算法 1.算法介绍 和聚类是有区别的聚类是没有标签的 数据集中必须包含明确的类别标签&#xff0c;即已知每个样本所属的类别。这些标签作为学习的目标&#xff0c;指导模型的训练过程。 2.应用场景 广泛应用于需要对数据进行明确分类和预测的场景&#xff0c;如医疗诊断…...

将 CrewAI 与 Elasticsearch 结合使用

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何使用 CrewAI 为你的代理团队创建一个 Elasticsearch 代理&#xff0c;并执行市场调研任务。 CrewAI 是一个用于编排代理的框架&#xff0c;它通过角色扮演的方式让多个代理协同完成复杂任务。 如果你想了解更多关于代理…...