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

(八)深入了解AVFoundation-采集:拍照功能的实现

引言

在上一篇文章中,我们初步完成了使用 AVFoundation 采集视频数据的流程,掌握了 AVCaptureSession 的搭建与视频流的预览显示。

本篇将继续深入 AVFoundation,聚焦于静态图片采集的实现。通过 AVCapturePhotoOutput,我们可以快速搭建起拍照功能,并获取高质量的照片数据。

本文将详细介绍拍照的基本流程,包括如何创建输出、配置拍照参数、处理拍照回调,以及如何将拍摄到的照片保存到系统相册。结合实际示例,带你完成一套完整、稳定的拍照功能搭建。

在早期的 iOS 开发中,我们常常使用 AVCaptureStillImageOutput 来实现拍照功能。但从 iOS 10 开始,Apple 推荐使用更强大、功能更全面的 AVCapturePhotoOutput 进行静态图片采集。AVCapturePhotoOutput 不仅统一了拍照接口,还支持 HEIF 格式、Live Photo、深度数据、RAW 拍摄等高级特性,能够更好地满足高质量拍摄的需求。

接下来,我们将基于 AVCapturePhotoOutput,搭建一个基础的拍照流程。

搭建拍照功能

为了更好地管理拍照流程,我们将功能封装到一个自定义的PHCaptureController类中,负责完成会话的搭建、控制与拍照等操作。

整个拍照流程主要包括以下几个步骤:

  1. 配置 AVCaptureSession。
  2. 添加摄像头输入。
  3. 添加照片输出。
  4. 启动与停止会话。
  5. 处理拍照请求与回调。

下面我们来逐一实现。

1. 类的基本结构

我们先来创建一个PHCaptureController类,大致结构如下:

//
//  PHCaptureController.swift
//  PHCaptureExample
//
//  Created by Louis on 2025/4/23.
// 负责会话控制及拍照操作import UIKit
import AVFoundationclass PHCaptureController:NSObject {/// 会话private let session = AVCaptureSession()/// 输出private let photoOutput = AVCapturePhotoOutput()/// 输入private var captureDeviceInput: AVCaptureDeviceInput?/// 队列private let sessionQueue = DispatchQueue(label: "com.example.captureSession")/// 代理weak var delegate: PHCaptureProtocol?init() {}/// 配置会话func setupConfigureSession() { }/// 启动会话func startSession() { }/// 停止会话func stopSession() { }/// 拍照func takePhoto() { }}

可以看到我们在类的内部维护了:

  1. session:采集会话。
  2. photoOutput:用于拍照的会话输出。
  3. captureDeviceInput:当前使用的会话输入。
  4. sessionQueue:串行队列,保证采集相关操作的线程安全。
  5. delegate:代理,负责错误和结果的回调。

PHCaptureProtocol 实现如下:

//
//  PHCaptureProtocol.swift
//  PHCaptureExample
//
//  Created by Louis on 2025/4/23.
//import Foundation
import UIKitprotocol PHCaptureProtocol:NSObjectProtocol {/// 发生错误func captureError(_ error: Error)/// 拍照回调func capturePhoto(_ image: UIImage)}

包含了:

  1. captureError:发生错误的回调方法。
  2. capturePhoto:拍照结果的回调方法。

2. 配置采集会话

我们在 setupConfigureSession 方法中需要完成三个操作:

  1. 设置会话预设。
  2. 添加摄像头输入。
  3. 添加照片输出。

并且保证这些操作需要在会话 beginConfiguration 与 commitConfiguration 方法之间执行。

    /// 配置会话func setupConfigureSession() {session.beginConfiguration()// 1.设置会话预设setupSessionPreset()// 2.设置会话输入if !setupSessionInput() {delegate?.captureError(NSError(domain: "PHCaptureController", code: 1001, userInfo: [NSLocalizedDescriptionKey: "Failed to add input"]))return}// 3.设置会话输出if !setupSessionOutput() {delegate?.captureError(NSError(domain: "PHCaptureController", code: 1002, userInfo: [NSLocalizedDescriptionKey: "Failed to add output"]))return}session.commitConfiguration()}

2.1 设置会话预设

就是设置分辨率,比如高质量照片。

    /// 设置会话话预设private func setupSessionPreset() {session.sessionPreset = .photo}

2.2 设置会话输入

添加摄像头设备,并包装一层 AVCaptureDeviceInput 添加到会话中。

    /// 设置会话输入private func setupSessionInput() -> Bool {guard let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video,position: .back) else { return false }do {captureDeviceInput = try AVCaptureDeviceInput(device: device)if session.canAddInput(captureDeviceInput!) {session.addInput(captureDeviceInput!)return true} else {return false}} catch {delegate?.captureError(error)return false}}
  1. 首先要确保获取到了摄像头设备。
  2. 检测输入是否可以被添加到会话。
  3. 如果出现错误则直接回调。

2.3 设置会话输出

将图片输出添加到会话。

    /// 设置会话输出private func setupSessionOutput() -> Bool {if session.canAddOutput(photoOutput) {session.addOutput(photoOutput)return true} else {return false}}

添加输出时也要检测是否可以被添加到会话。

3. 会话的启动与停止

我们使用单独的串行队列来管理会话的启动与停止,避免出现线程问题。

    /// 启动会话func startSession() {sessionQueue.async {if !self.session.isRunning {self.session.startRunning()}}}/// 停止会话func stopSession() {sessionQueue.async {if self.session.isRunning {self.session.stopRunning()}}}

4. 拍照

在拍照的方法里设置拍照参数和代理,并实现 AVCapturePhotoCaptureDelegate 的代理方法。

    /// 拍照func takePhoto() {let settings = AVCapturePhotoSettings()settings.flashMode = .autosettings.isHighResolutionPhotoEnabled = truesessionQueue.async {self.photoOutput.capturePhoto(with: settings, delegate: self)}}//MARK: - AVCapturePhotoCaptureDelegatefunc photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: (any Error)?) {if let error = error {delegate?.captureError(error)return}guard let imageData = photo.fileDataRepresentation() else {delegate?.captureError(NSError(domain: "PHCaptureController", code: 1003, userInfo: [NSLocalizedDescriptionKey: "Failed to get image data"]))return}guard let image = UIImage(data: imageData) else {delegate?.captureError(NSError(domain: "PHCaptureController", code: 1004, userInfo: [NSLocalizedDescriptionKey: "Failed to create image"]))return}delegate?.capturePhoto(image)}

整个拍照的核心功能就已经搭建完成了,接下来我们只需要添加画面预览,就可以调用这个类来实现完整的拍照功能了。

5. 画面预览

为了能够实时显示摄像头画面,我们需要一个专门的预览视图。

在 AVFoundation 中,通常通过 AVCaptureVideoPreviewLayer 来实现摄像头画面渲染,因此我们可以自定义一个简单的 PHPreviewView。

import UIKit
import AVFoundationclass PHPreviewView: UIView {override class var layerClass: AnyClass {return AVCaptureVideoPreviewLayer.self}private var previewLayer: AVCaptureVideoPreviewLayer {return layer as! AVCaptureVideoPreviewLayer}func setSession(_ session: AVCaptureSession) {previewLayer.session = sessionpreviewLayer.videoGravity = .resizeAspectFill}
}

使用拍照功能

接下来我们只需要在视图控制器中,非常简单的接入一下拍照的控制器和预览视图就可以使用拍照功能咯。

import UIKit
import AVFoundationclass ViewController: UIViewController,PHCaptureProtocol {/// 拍照控制器let captureController = PHCaptureController()/// 预览视图let previewView = PHPreviewView()override func viewDidLoad() {super.viewDidLoad()captureController.setupConfigureSession()captureController.delegate = selfcaptureController.startSession()previewView.setSession(captureController.session)view.addSubview(previewView)previewView.frame = view.bounds}//MARK: - PHCaptureProtocolfunc captureError(_ error: any Error) {}func capturePhoto(_ image: UIImage) {}}

结语

在本篇中,我们基于 AVFoundation 框架,搭建了一个基本的拍照功能实现流程:

包括配置 AVCaptureSession、添加 AVCaptureDeviceInput 和 AVCapturePhotoOutput、设置预览视图 PHPreviewView,并通过 AVCapturePhotoCaptureDelegate 拿到照片数据,为后续保存、展示、处理照片打下了基础。

需要特别注意的是:在正式使用相机功能之前,务必进行权限申请和检测。

如果未申请或未获得相机访问权限,直接启动 AVCaptureSession 会导致应用崩溃或黑屏。

通常,我们会在 App 启动或功能入口时,通过 AVCaptureDevice.requestAccess(for: .video) 请求权限,并根据权限结果决定是否继续初始化采集相关流程。

到这里,我们已经完成了拍照功能的基本搭建,感谢大家的阅读。

 

 

 

 

相关文章:

(八)深入了解AVFoundation-采集:拍照功能的实现

引言 在上一篇文章中,我们初步完成了使用 AVFoundation 采集视频数据的流程,掌握了 AVCaptureSession 的搭建与视频流的预览显示。 本篇将继续深入 AVFoundation,聚焦于静态图片采集的实现。通过 AVCapturePhotoOutput,我们可以…...

C++区别于C语言的提升用法(万字总结)

1.namespace产生原因 在C语言中,变量,函数,以至于类都是大量存在的,因此会产生大量的名称存在于全局作用域中,可能产生很多冲突,至此c的祖师爷为避免命名冲突和名字的污染,造出来了关键字names…...

创新项目实训开发日志4

一、开发简介 核心工作内容&#xff1a;logo实现、注册实现、登录实现、上传gitee 工作时间&#xff1a;第十周 二、logo实现 1.设计logo 2.添加logo const logoUrl new URL(/assets/images/logo.png, import.meta.url).href <div class"aside-first">…...

ospf综合作业

需求 需求分析 区域划分&#xff1a; 网络划分为 area 0、area 1、area 2、area 3、area 4 多个区域。其中 area 0 作为骨干区域&#xff0c;其他为非骨干区域。这种划分符合 OSPF&#xff08;开放式最短路径优先&#xff09;协议中区域设计原则&#xff0c;不同区域通过 ABR…...

旋转磁体产生的场-对导航姿态的影响

pitch、yaw、roll是描述物体在空间中旋转的术语&#xff0c;通常用于计算机图形学或航空航天领域中。这些术语描述了物体绕不同轴旋转的方式&#xff1a; Pitch&#xff08;俯仰&#xff09;&#xff1a;绕横轴旋转&#xff0c;使物体向前或向后倾斜。俯仰角度通常用来描述物体…...

Hive 数据同步到 Doris 最佳实践方案:从场景适配到性能调优全解析

在大数据领域&#xff0c;Hive 作为成熟的数据仓库解决方案&#xff0c;常用于海量数据存储与离线处理&#xff0c;而 Doris 凭借其强大的 OLAP 能力&#xff0c;在实时分析、即席查询等场景表现卓越。当企业需要将 Hive 数据仓库中的数据与 Doris 的分析能力结合时&#xff0c…...

netty中的Channel与Java NIO中的Channel核心对比

Netty的Channel和Java NIO的Channel虽然都用于网络通信,但设计理念、功能扩展及适用场景存在显著差异。以下从核心特性、设计模式及性能优化等维度展开对比: 1. 抽象层次与功能范围 Java NIO Channel 基础IO模型:仅支持非阻塞IO(NIO),如SocketChannel、ServerSocketChann…...

基于whisper和ffmpeg语音转文本小程序

目录 一、环境准备 ✅ 第一步&#xff1a;安装并准备 Conda 环境 ✅ 第二步&#xff1a;创建 Whisper 专用的 Conda 虚拟环境 ✅ 第三步&#xff1a;安装 GPU 加速版 PyTorch&#xff08;适配 RTX 4060&#xff09; ✅ 第四步&#xff1a;安装 Whisper 和 FFMPEG 依赖 ✅…...

使用ffmpeg 将图片合成为视频,填充模糊背景,并添加两段音乐

1.输入3张图片,每张播放一次,播放两秒,视频分辨率设置为1920:1080,每张图片前0.3秒淡入,后0.3秒淡出,图片宽高比不变,用白色填充空白区域 ffmpeg -loop 1 -t 2 -i "img1.jpg" \-loop 1 -t 2 -i "img2.jpg" \-loop 1 -t 2 -i "img3.jpg" \-filte…...

Python协程详解:从基础到实战

协程是Python中实现并发编程的重要方式之一&#xff0c;它比线程更轻量级&#xff0c;能够高效处理I/O密集型任务。本文将全面介绍协程的概念、原理、实现方式以及与线程、进程的对比&#xff0c;包含完整的效率对比代码和详细说明&#xff0c;帮助Python开发者深入理解并掌握协…...

服务器部署LLaMAFactory进行LoRA微调

一、什么是LLaMAFactory LlamaFactory 是一个专为 大型语言模型&#xff08;LLM&#xff09;微调 设计的开源工具库&#xff0c;旨在简化大模型&#xff08;如 LLaMA、GPT、Mistral 等&#xff09;的定制化训练流程&#xff0c;降低技术门槛和硬件成本。以下是它的核心功能和应…...

ASP.NET MVC​ 入门指南

以下是一份 MVC&#xff08;Model - View - Controller&#xff09;培训教程&#xff0c;以ASP.NET MVC 为例进行讲解&#xff0c;适合有一定编程基础的学习者快速上手。 1. MVC 概述 1.1 什么是 MVC MVC 是一种软件设计模式&#xff0c;它将应用程序分为三个主要部分&#…...

mapbox高阶,高程影像、行政区边界阴影效果实现

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️line线图层样式1.4 ☘️symbol符号图层…...

如何下载适用于语音识别功能增强的Google Chrome浏览器

谷歌浏览器一直是互联网用户的首选工具之一&#xff0c;尤其是它强大的扩展功能&#xff0c;使得用户可以根据需求定制浏览器。对于需要使用语音识别功能的用户来说&#xff0c;谷歌浏览器提供了优秀的支持&#xff0c;通过简单的设置和插件&#xff0c;可以显著提升语音识别的…...

运维打铁:Centos 7 安装 redis_exporter 1.3.5

文章目录 一、CentOS 7 安装 redis_exporter 1.3.51. 安装2. 配置自启动&#xff0c;并连接 Redis&#xff0c;修改端口3. 配置 Prometheus 采集 redis_exporter 数据4. 配置 Grafana 查看数据5. Redis 集群配置 二、常见问题及解决办法1. 下载二进制包失败2. 解压部署时权限问…...

3台CentOS虚拟机部署 StarRocks 1 FE+ 3 BE集群

背景&#xff1a;公司最近业务数据量上去了&#xff0c;需要做一个漏斗分析功能&#xff0c;实时性要求较高&#xff0c;mysql已经已经不在适用&#xff0c;做了个大数据技术栈选型调研后&#xff0c;决定使用StarRocks StarRocks官网&#xff1a;StarRocks | A High-Performa…...

Oracle 11g RAC ASM磁盘组剔盘、加盘实施过程

环境&#xff1a;AIX6.1 Oracle RAC 11.2.0.3 前期准备&#xff1a; 1.查看DG磁盘组空间情况&#xff1a; –查看DG磁盘组空间情况&#xff1a; ASMCMD> lsdg State Type Rebal Sector Block AU Total_MB Free_MB Req_mir_free_MB Usable_file_MB Of…...

网站高可用架构设计基础——高可用策略和架构原则

一、正面保障与减少损失 要想让系统能够稳定可用&#xff0c;首先要考虑如何避免问题的发生。比如说可以通过 UPS&#xff08;不间断电源&#xff09;来避免服务器断电&#xff0c;可以通过事先增加机器来解决硬件资源不足的问题。 然后&#xff0c;如果问题真的发生了&#…...

从入门到精通【MySQL】视图与用户权限管理

文章目录 &#x1f4d5;1. 视图✏️1.1 视图的基本概念✏️1.2 试图的基本操作&#x1f516;1.2.1 创建视图&#x1f516;1.2.2 使用视图&#x1f516;1.2.3 修改数据&#x1f516;1.2.4 删除视图 ✏️1.3 视图的优点 &#x1f4d5;2. 用户与权限管理✏️2.1 用户&#x1f516;…...

使用QML Tumbler 实现时间日期选择器

目录 引言相关阅读项目结构示例实现与代码解析示例一&#xff1a;时间选择器&#xff08;TimePicker&#xff09;示例二&#xff1a;日期时间选择器&#xff08;DateTimePicker&#xff09; 主窗口整合运行效果总结下载链接 引言 在现代应用程序开发中&#xff0c;时间与日期选…...

[golang] 介绍 | 特点 | 应用场景

“编程不仅仅是写代码&#xff0c;更是一种思考方式。” 参考资料 《Unix编程环境》- Brian W. Kernighan, Rob Pike《程序设计实践》- Brian W. Kernighan, Rob PikeGo语言官方网站&#xff1a;https://golang.orgRob Pike的个人博客&#xff1a;http://herpolhode.com/rob/ …...

Python 爬虫实战 | 企名科技

文章目录 一、企名科技1、目标网站2、网站特点3、确定解密位置4、扣js代码 一、企名科技 1、目标网站 网址&#xff1a;https://wx.qmpsee.com/articleDetail?idfeef62bfdac45a94b9cd89aed5c235be目标数据&#xff1a;获取消费行业研究下面的13篇文章数据 2、网站特点 服…...

c加加学习之day06->STL标准库->day01

1.介绍&#xff1a;C 标准模板库&#xff08;Standard Template Library&#xff0c;简称 STL&#xff09;是一组泛型编程的模板类和函数&#xff0c;旨在提供常用的数据结构、算法和函数对象。STL 是 C 标准库的一部分&#xff0c;极大地提高了编程效率和代码的可重用性。STL …...

并发设计模式实战系列(6):读写锁

&#x1f31f; ​大家好&#xff0c;我是摘星&#xff01;​ &#x1f31f; 今天为大家带来的是并发设计模式实战系列&#xff0c;第六章读写锁模式​​&#xff0c;废话不多说直接开始~ 目录 一、核心原理深度拆解 1. 读写锁三维模型 2. 关键实现原理 二、生活化类比&am…...

【网络原理】从零开始深入理解TCP的各项特性和机制.(一)

本篇博客给大家带来的是网络原理的相关知识.其中传输层这一部分非常重要,面试中只要是涉及到网络这一部分知识,几乎是必定会考传输层TCP的. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给…...

基于Pytorch的深度学习-第二章

2.1 CIFAR-10数据集简介 CIFAR-10数据集包含10个类别&#xff1a;plane、car、bird、cat、deer、dog、frog、horse、ship、truck&#xff0c;每个类别有6000张图片。其中训练集图片有50000张&#xff0c;测试集有10000张图片。训练集和测试集的生成方法是&#xff0c;分别从每…...

gitlab-ce容器镜像源(国内)

下载命令 docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gitlab/gitlab-ce:17.10.4-ce.0 更多参考&#xff1a; https://docker.aityp.com/image/docker.io/gitlab/gitlab-ce:17.10.4-ce.0...

TinyVue v3.22.0 正式发布:深色模式上线!集成 UnoCSS 图标库!TypeScript 类型支持全面升级!

我们非常高兴地宣布&#xff0c;2025年4月7日&#xff0c;TinyVue发布了v3.22.0&#x1f389;。 本次 3.22.0 版本主要有以下重大变更&#xff1a; 支持深色模式增加基于 UnoCSS 的图标库更丰富的 TypeScript 类型声明支持 XSS 配置 详细的 Release Notes 请参考&#xff1a…...

Browser-Use WebUI:让AI自动使用浏览器帮你查询信息执行任务

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

使用PyTorch如何配置一个简单的GTP

目录 一、什么是GPT 1. Transformer Block 的核心结构​ ​2. 关键组件解析​ ​​(1) 掩码多头自注意力&#xff08;Masked Multi-Head Self-Attention&#xff09;​​ ​​(2) 前馈神经网络&#xff08;FFN&#xff09;​​ ​​(3) 层归一化&#xff08;LayerNorm&…...

【FAQ】针对于消费级NVIDIA GPU的说明

概述 本文概述 HP Anyware 在配备消费级 NVIDIA GPU 的物理工作站上的关​​键组件、安装说明和重要注意事项。 注意&#xff1a;本文档适用于 NVIDIA 消费级 GPU。NVIDIA Quadro 和 Tesla GPU 也支持 HP Anyware 在公有云、虚拟化或物理工作站环境中运行。请参阅PCoIP Graphi…...

02_java的运行机制以及JDKJREJVM基本介绍

1、运行机制 2、JDK&JRE&JVM JDK 基本介绍 &#xff08;1&#xff09; JDK 的全称(Java Development Kit Java开发工具包) JDK JRE java的开发工具 [ java, javac, javadoc, javap等 ] &#xff08;2&#xff09;JDK是提供给Java开发人员使用的&#xff0c;其…...

go 的 net 包

目录 一、net包的基本功能 1.1 IP地址处理 1.2 网络协议支持 1.3 连接管理 二、net包的主要功能模块 2.1 IP地址处理 2.2 TCP协议 2.3 UDP协议 2.4 Listener和Conn接口 三、高级功能 3.1 超时设置 3.2 KeepAlive控制 3.3 获取连接信息 四、实际应用场景 4.1 Web服…...

ShenNiusModularity项目源码学习(21:ShenNius.Admin.Mvc项目分析-6)

菜单列表页面用于新建、维护及删除系统所有模块所需的菜单信息&#xff0c;包括菜单名称、菜单中的按钮、菜单关联的后台服务地址及请求方式等。菜单列表页面的后台控制器类MenuController位于ShenNius.Admin.Mvc项目的Areas\Sys\Controllers内&#xff0c;页面文件位于同项目的…...

基于单片机的游泳馆智能管理系统

标题:基于单片机的游泳馆智能管理系统 内容:1.摘要 随着人们生活水平的提高&#xff0c;游泳馆的规模和客流量不断增大&#xff0c;传统的管理方式已难以满足高效、便捷的管理需求。本研究的目的是设计并实现一种基于单片机的游泳馆智能管理系统。方法上&#xff0c;采用单片机…...

开发了一个b站视频音频提取器

B站资源提取器-说明书 一、功能说明 本程序可自动解密并提取B站客户端缓存的视频资源&#xff0c;支持以下功能&#xff1a; - 自动识别视频缓存目录 - 将加密的.m4s音频文件转换为标准MP3格式 - 将加密的.m4s视频文件转换为标准MP4格式&#xff08;合并音视频流&#xff09;…...

vue2项目,为什么开发环境打包出来的js文件名是1.js 2.js,而生产环境打包出来的是chunk-3adddd.djncjdhcbhdc.js

Vue2项目开发环境与生产环境JS文件名差异的核心原理及配置逻辑如下&#xff1a; 一、文件名差异的底层机制 1‌、Webpack默认命名策略‌ 开发环境默认禁用哈希&#xff0c;采用[id].js命名规则&#xff08;如1.js&#xff09;&#xff0c;生产环境启用[chunkhash]生成chunk-xxx…...

SQL进阶知识:六、动态SQL

今天介绍下关于动态SQL的详细介绍&#xff0c;并结合MySQL数据库提供实际例子。 动态SQL是指在运行时动态构建和执行SQL语句的技术。这种技术在处理复杂的查询逻辑、参数化查询或在某些情况下需要根据用户输入动态调整查询时非常有用。MySQL支持动态SQL&#xff0c;主要通过PRE…...

Spring Boot常用注解详解:实例与核心概念

Spring Boot常用注解详解&#xff1a;实例与核心概念 前言 Spring Boot作为Java领域最受欢迎的快速开发框架&#xff0c;其核心特性之一是通过注解&#xff08;Annotation&#xff09;简化配置&#xff0c;提高开发效率。注解驱动开发模式让开发者告别繁琐的XML配置&#xff…...

java 富文本转pdf

前言&#xff1a; 本文的目的是将传入的富文本内容(html标签&#xff0c;图片)并且分页导出为pdf。 所用的核心依赖为iText7。 因为itextpdf-core的核心包在maven中央仓库中&#xff0c;阿里云华为云等拉不下来&#xff0c;中央仓库在外网&#xff0c;并且此包在中央仓库中未…...

17.第二阶段x64游戏实战-人工遍历二叉树结构

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;16.第二阶段x64游戏实战-分析二叉树结构 上一个内容里把二叉树的结构写了写&am…...

C#基于Sunnyui框架和MVC模式实现用户登录管理

C#基于Sunnyui框架和MVC模式实现用户登录管理 1 Controller1.1 UserManagementController.cs&#xff08;控制器入口&#xff09; 2 Model2.1 UserRepository.cs&#xff08;用户管理模型&#xff09;2.2 User.cs&#xff08;用户结构体&#xff09;2.3 SQLiteHelper.cs&#x…...

Spring Boot实战(三十六)编写单元测试

目录 一、什么是单元测试&#xff1f;二、Spring Boot 中的单元测试依赖三、举例 Spring Boot 中不同层次的单元测试3.1 Service层3.2 Controller 层3.3 Repository层 四、Spring Boot 中 Mock、Spy 对象的使用4.1 使用Mock对象的背景4.2 什么是Mock对象&#xff0c;有哪些好处…...

声音分离人声和配乐-从头设计数字生命第4课——仙盟创梦IDE

音频分离在数字人中具有多方面的重要作用&#xff0c;主要体现在以下几个方面&#xff1a; 提高语音合成质量&#xff1a;通过音频分离&#xff0c;可以将原始音频中的语音部分与其他背景噪音或干扰声音分离开来。这样在进行语音合成时&#xff0c;能够获得更纯净的语音信号&am…...

http协议、全站https

一、http协议 1、为何要学http协议? 用户用浏览器访问网页,默认走的都是http协议,所以要深入研究web层,必须掌握http协议 2、什么是http协议 1、全称Hyper Text Transfer Protocol(超文本传输协议) ### 一个请求得到一个响应包 普通…...

Mediamtx与FFmpeg远程与本地推拉流使用

1.本地推拉流 启服 推流 ffmpeg -re -stream_loop -1 -i ./DJI_0463.MP4 -s 1280x720 -an -c:v h264 -b:v 2000k -maxrate 2500k -minrate 1500k -bufsize 3000k -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/stream 拉流 ffplay -rtsp_transport tcp rtsp://43.136.…...

css3新特性第七章(3D变换)

css新特性第七章(3D变换) 一、3d空间和景深 元素进行 3D 变换的首要操作&#xff1a;父元素必须开启 3D 空间&#xff01; 使用 transform-style 开启 3D 空间&#xff0c;可选值如下&#xff1a; flat &#xff1a; 让子元素位于此元素的二维平面内&#xff08; 2D 空间&…...

redis经典问题

1.缓存雪崩 指缓存同一时间大面积的失效&#xff0c;所以&#xff0c;后面的请求都会落到数据库上&#xff0c;造成数据库短时间内承受大量请求而崩掉。 解决方案&#xff1a; 1&#xff09;Redis 高可用&#xff0c;主从哨兵&#xff0c;Redis cluster&#xff0c;避免全盘崩…...

数据仓库是什么?数据仓库架构有哪些?

目录 数据仓库是什么&#xff1f;数据仓库架构有哪些&#xff1f; 一、数据仓库是什么&#xff1f; 二、数据仓库的架构分层 1. 获取层 2. 数据层 3. 应用层 4. 访问层 三、数据仓库的价值体现 1.决策支持 2.业务优化 3.提升竞争力 四、数据仓库的未来发展趋势 总…...

Nginx 通过 Let‘s Encrypt 实现 HTTPS 访问全流程指南

一、Let’s Encrypt 与 Certbot 简介 Let’s Encrypt 是由非营利组织 ISRG 运营的免费证书颁发机构&#xff08;CA&#xff09;&#xff0c;旨在推动 HTTPS 的普及。其核心工具 Certbot 能自动化完成证书申请、部署与续期&#xff0c;大幅降低 HTTPS 的配置复杂度。通过 Certb…...