从PPT到PNG:Python实现的高效PPT转图工具
从PPT到PNG:Python实现的高效PPT转图工具
在日常工作中,PPT(PowerPoint)文件是我们常用的演示工具。然而,有时候我们需要将PPT的内容提取为图片格式(如PNG)以便于展示或保存。手动将每一页PPT保存为图片不仅繁琐且容易出错。为了提高工作效率,我们可以通过编程自动化这一过程。本篇文章将详细介绍如何使用Python语言开发一款PPT转PNG工具,基于Tkinter图形界面和win32com库,支持批量PPT转图片及图像网格拼接功能。
1. 概述
本工具的目标是将PPT文件的每一页转换为高质量的PNG图片,并提供一个图形化界面,帮助用户快速选择PPT文件并完成转换操作。该工具的实现基于以下几个核心技术:
- Tkinter:Python标准库中的GUI工具,用于构建用户界面。
- win32com:通过调用PowerPoint的COM接口来操作PPT文件,实现文件转换。
- PIL(Pillow):Python Imaging Library,用于处理图像,包括图像的读取、修改和保存。
- psutil:用于检查并确保PowerPoint进程的安全退出,避免进程残留导致的错误。
核心功能
- PPT转PNG:将PPT中的每一页转换为PNG格式的图片。
- 图像网格拼接:将转换后的PNG图片按特定规则排列为一张大图,尽量保证输出图像的比例接近4:3。
- 图形界面:提供简洁直观的用户界面,支持文件选择、转换进度显示及转换状态提示。
2. 功能使用
2.1 安装依赖
首先,需要安装一些必要的Python库。在命令行中运行以下命令:
pip install pillow psutil pywin32
2.2 使用步骤
- 启动工具:运行程序后,打开的GUI界面包含了文件选择、进度条以及状态提示区域。
- 选择PPT文件:点击“浏览”按钮选择需要转换的PPT文件。只支持
.ppt
和.pptx
文件格式。 - 开始转换:选择文件后,点击“开始转换”按钮,程序会自动将PPT的每一页转换为PNG图片并保存到临时目录中。
- 创建网格图:转换完成后,程序会根据指定的列数将所有图片拼接为一张大图。最终输出图像的比例尽量接近4:3。
- 查看结果:转换完成后,程序会显示输出文件的保存路径,并提供成功提示。
2.3 代码实现
2.3.1 PPT转换为PNG
PPT文件的转换操作依赖于PowerPoint的COM接口。通过win32com.client.DispatchEx
我们可以启动PowerPoint应用,加载PPT文件并提取每一页为PNG图片。
def ppt_to_images(ppt_path, output_dir):"""将PPT转换为图片"""if not os.path.exists(output_dir):os.makedirs(output_dir)ppt_path = os.path.abspath(ppt_path)try:for proc in psutil.process_iter(['name']):if proc.info['name'] and 'powerpnt' in proc.info['name'].lower():proc.kill()except:passtime.sleep(1)max_retries = 3retry_count = 0last_error = Nonepowerpoint = Nonewhile retry_count < max_retries:try:powerpoint = win32com.client.DispatchEx("PowerPoint.Application")powerpoint.Visible = 1powerpoint.DisplayAlerts = 0presentation = powerpoint.Presentations.Open(ppt_path, WithWindow=False)total_slides = presentation.Slides.Countfor i in range(1, total_slides + 1):image_path = os.path.join(output_dir, f'slide_{i:03d}.png')slide = presentation.Slides(i)slide.Export(image_path, "PNG", 1920, 1080)time.sleep(0.5)presentation.Close()returnexcept Exception as e:retry_count += 1last_error = eif retry_count >= max_retries:raise Exception(f"PowerPoint转换失败,已重试{max_retries}次。错误信息: {str(last_error)}")time.sleep(2)
2.3.2 图像网格拼接
对于转换后的每一张PNG图片,程序将尝试按不同的列数排列,以获得接近4:3的图像比例。
def create_grid_image(image_dir, output_path, target_width=1920):"""将图片紧凑排列,并使最终图片比例接近4:3"""image_files = sorted([f for f in os.listdir(image_dir) if f.endswith('.png')])if not image_files:raise Exception("没有找到转换后的图片文件!")images = [Image.open(os.path.join(image_dir, img_file)) for img_file in image_files]best_cols = 1best_ratio_diff = float('inf')best_layout = Nonefor num_cols in range(1, 6):layout, row_heights = [], []current_row, max_row_height = [], 0for img in images:scale = (target_width / num_cols) / img.widthnew_width = int(img.width * scale)new_height = int(img.height * scale)current_row.append((new_width, new_height))max_row_height = max(max_row_height, new_height)if len(current_row) == num_cols:layout.append(current_row)row_heights.append(max_row_height)current_row, max_row_height = [], 0if current_row:layout.append(current_row)row_heights.append(max_row_height)total_width = target_widthtotal_height = sum(row_heights)target_ratio = 4/3actual_ratio = total_width / total_heightratio_diff = abs(target_ratio - actual_ratio)if ratio_diff < best_ratio_diff:best_ratio_diff = ratio_diffbest_cols = num_colsbest_layout = (layout, row_heights)layout, row_heights = best_layoutcanvas = Image.new('RGB', (target_width, sum(row_heights)), 'white')y = 0img_index = 0for row, row_height in zip(layout, row_heights):x = 0for width, height in row:if img_index < len(images):img = images[img_index].resize((width, height), Image.Resampling.LANCZOS)canvas.paste(img, (x, y))x += widthimg_index += 1y += row_heightcanvas.save(output_path, quality=95)
2.4 GUI界面
GUI使用Tkinter
构建,包含了文件选择框、转换进度条、状态标签和按钮,确保用户能够直观地使用该工具进行PPT转换。
class PPTConverterGUI:def __init__(self, root):self.root = rootself.root.title("PPT转JPG工具")self.root.geometry("600x400")...def browse_file(self):file_path = filedialog.askopenfilename(filetypes=[("PowerPoint文件", "*.ppt;*.pptx")])if file_path:self.file_path.set(file_path)logging.info(f"选择了文件: {file_path}")def start_conversion(self):ppt_path = self.file_path.get()...thread = threading.Thread(target=self.convert_ppt, args=(ppt_path,))thread.start()
3.效果展示
生成jpg图片效果图
:
4.相关源码
import os
from PIL import Image
import tempfile
import win32com.client
import time
import math
import tkinter as tk
from tkinter import filedialog, ttk, messagebox
import threading
import traceback
import logging
import psutil# 配置日志
logging.basicConfig(filename='ppt_converter.log',level=logging.DEBUG,format='%(asctime)s - %(levelname)s - %(message)s'
)def ppt_to_images(ppt_path, output_dir):"""将PPT转换为图片"""# 创建临时目录if not os.path.exists(output_dir):os.makedirs(output_dir)# 确保使用绝对路径ppt_path = os.path.abspath(ppt_path)# 确保PowerPoint进程已完全退出try:for proc in psutil.process_iter(['name']):if proc.info['name'] and 'powerpnt' in proc.info['name'].lower():proc.kill()except:passtime.sleep(1) # 等待进程完全退出max_retries = 3retry_count = 0last_error = Nonepowerpoint = Nonewhile retry_count < max_retries:try:# 使用PowerPoint COM对象powerpoint = win32com.client.DispatchEx("PowerPoint.Application")try:# 设置PowerPoint为可见(有些系统必须设置为可见才能工作)powerpoint.Visible = 1powerpoint.DisplayAlerts = 0# 打开演示文稿presentation = powerpoint.Presentations.Open(ppt_path,WithWindow=False # 尝试不显示窗口)# 遍历每一页并保存为图片total_slides = presentation.Slides.Countfor i in range(1, total_slides + 1):image_path = os.path.join(output_dir, f'slide_{i:03d}.png')slide = presentation.Slides(i)slide.Export(image_path, "PNG", 1920, 1080) # 指定分辨率time.sleep(0.5) # 给PowerPoint一些时间来处理# 正常关闭presentation.Close()return # 成功完成,退出函数finally:# 确保清理资源if powerpoint:try:powerpoint.Quit()except:passfinally:powerpoint = Noneexcept Exception as e:retry_count += 1last_error = e# 确保PowerPoint被关闭if powerpoint:try:powerpoint.Quit()except:passfinally:powerpoint = Noneif retry_count >= max_retries:error_msg = f"PowerPoint转换失败,已重试{max_retries}次。错误信息: {str(last_error)}"logging.error(error_msg)raise Exception(error_msg)logging.info(f"第{retry_count}次尝试失败,等待后重试...")time.sleep(2) # 等待一段时间后重试raise Exception("PowerPoint转换失败,超过最大重试次数")def create_grid_image(image_dir, output_path, target_width=1920):"""将图片紧凑排列,并使最终图片比例接近4:3"""# 获取所有图片文件image_files = sorted([f for f in os.listdir(image_dir) if f.endswith('.png')])if not image_files:raise Exception("没有找到转换后的图片文件!")# 读取所有图片images = []for img_file in image_files:img = Image.open(os.path.join(image_dir, img_file))images.append(img)# 找到最佳的列数,使最终图片比例最接近4:3best_cols = 1best_ratio_diff = float('inf')best_layout = None# 尝试不同的列数(1到5列)for num_cols in range(1, 6):# 计算这个列数下的布局layout = []current_row = []row_heights = []max_row_height = 0for img in images:# 计算缩放后的尺寸scale = (target_width / num_cols) / img.widthnew_width = int(img.width * scale)new_height = int(img.height * scale)current_row.append((new_width, new_height))max_row_height = max(max_row_height, new_height)if len(current_row) == num_cols:layout.append(current_row)row_heights.append(max_row_height)current_row = []max_row_height = 0# 处理最后一行if current_row:layout.append(current_row)row_heights.append(max_row_height)# 计算总宽度和高度total_width = target_widthtotal_height = sum(row_heights)# 计算与4:3比例的差异target_ratio = 4/3actual_ratio = total_width / total_heightratio_diff = abs(target_ratio - actual_ratio)# 更新最佳列数if ratio_diff < best_ratio_diff:best_ratio_diff = ratio_diffbest_cols = num_colsbest_layout = (layout, row_heights)# 使用最佳列数创建最终图片layout, row_heights = best_layoutcanvas_width = target_widthcanvas_height = sum(row_heights)canvas = Image.new('RGB', (canvas_width, canvas_height), 'white')# 拼接图片y = 0img_index = 0for row, row_height in zip(layout, row_heights):x = 0for width, height in row:if img_index < len(images):img = images[img_index]img = img.resize((width, height), Image.Resampling.LANCZOS)canvas.paste(img, (x, y))x += widthimg_index += 1y += row_height# 裁剪掉多余的空白部分bbox = canvas.getbbox()if bbox:canvas = canvas.crop(bbox)# 保存最终图片canvas.save(output_path, quality=95)class PPTConverterGUI:def __init__(self, root):self.root = rootself.root.title("PPT转JPG工具")self.root.geometry("600x400")# 设置主题样式style = ttk.Style()style.configure("TButton", padding=6, relief="flat", background="#2196F3")style.configure("TLabel", padding=6, font=('微软雅黑', 10))# 创建主框架main_frame = ttk.Frame(root, padding="20")main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))# 标题title_label = ttk.Label(main_frame, text="PPT转JPG工具", font=('微软雅黑', 16, 'bold'))title_label.grid(row=0, column=0, columnspan=2, pady=20)# 文件选择区域file_frame = ttk.LabelFrame(main_frame, text="选择PPT文件", padding="10")file_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=10)self.file_path = tk.StringVar()self.file_entry = ttk.Entry(file_frame, textvariable=self.file_path, width=50)self.file_entry.grid(row=0, column=0, padx=5)browse_button = ttk.Button(file_frame, text="浏览", command=self.browse_file)browse_button.grid(row=0, column=1, padx=5)# 转换按钮self.convert_button = ttk.Button(main_frame, text="开始转换", command=self.start_conversion)self.convert_button.grid(row=2, column=0, columnspan=2, pady=20)# 进度条self.progress = ttk.Progressbar(main_frame, length=400, mode='indeterminate')self.progress.grid(row=3, column=0, columnspan=2, pady=10)# 状态标签self.status_label = ttk.Label(main_frame, text="")self.status_label.grid(row=4, column=0, columnspan=2, pady=10)# 配置网格权重main_frame.columnconfigure(0, weight=1)main_frame.columnconfigure(1, weight=1)def browse_file(self):file_path = filedialog.askopenfilename(filetypes=[("PowerPoint文件", "*.ppt;*.pptx")])if file_path:self.file_path.set(file_path)logging.info(f"选择了文件: {file_path}")def start_conversion(self):ppt_path = self.file_path.get()if not ppt_path:messagebox.showerror("错误", "请先选择PPT文件!")returnif not os.path.exists(ppt_path):messagebox.showerror("错误", "文件不存在!")return# 禁用按钮并显示进度条self.convert_button.state(['disabled'])self.progress.start()self.status_label.config(text="正在转换中...")# 在新线程中执行转换thread = threading.Thread(target=self.convert_ppt, args=(ppt_path,))thread.start()def convert_ppt(self, ppt_path):temp_dir = Nonetry:logging.info(f"开始转换PPT文件: {ppt_path}")# 创建临时目录temp_dir = tempfile.mkdtemp()logging.info(f"创建临时目录: {temp_dir}")output_path = os.path.join(os.path.dirname(ppt_path), "output_grid_image.png")logging.info(f"输出路径: {output_path}")# 转换PPT为图片logging.info("开始转换PPT为图片...")ppt_to_images(ppt_path, temp_dir)logging.info("PPT转图片完成")# 创建网格图logging.info("开始创建网格图...")create_grid_image(temp_dir, output_path)logging.info("网格图创建完成")# 清理临时文件logging.info("清理临时文件...")for file in os.listdir(temp_dir):os.remove(os.path.join(temp_dir, file))os.rmdir(temp_dir)logging.info("临时文件清理完成")# 更新UIself.root.after(0, self.conversion_complete, output_path)except Exception as e:error_msg = f"转换失败: {str(e)}\n{traceback.format_exc()}"logging.error(error_msg)self.root.after(0, self.conversion_error, error_msg)finally:# 确保清理临时文件if temp_dir and os.path.exists(temp_dir):try:for file in os.listdir(temp_dir):os.remove(os.path.join(temp_dir, file))os.rmdir(temp_dir)except Exception as e:logging.error(f"清理临时文件失败: {str(e)}")def conversion_complete(self, output_path):self.progress.stop()self.convert_button.state(['!disabled'])self.status_label.config(text=f"转换完成!输出文件保存在: {output_path}")messagebox.showinfo("成功", "PPT转换完成!")def conversion_error(self, error_msg):self.progress.stop()self.convert_button.state(['!disabled'])self.status_label.config(text="转换失败!")messagebox.showerror("错误", f"转换过程中出现错误: {error_msg}")def main():root = tk.Tk()app = PPTConverterGUI(root)root.mainloop()if __name__ == "__main__":main()
5. 总结
通过本篇文章,您已经了解了如何使用Python编写一款PPT转图片的工具。我们通过Tkinter构建了一个简洁的GUI界面,通过win32com调用PowerPoint的COM接口进行文件转换,并通过Pillow处理图像拼接。无论是用于日常的文件转换,还是处理多个PPT文件,本工具都能大大提高工作效率。
此工具的扩展性也很强,您可以根据需要进一步优化图像的处理过程,或者增加更多的自定义功能,例如支持更多格式的转换,添加批量处理功能等。希望本教程能帮助您更好地实现PPT转图片的自动化,提升工作效率。
相关文章:
从PPT到PNG:Python实现的高效PPT转图工具
从PPT到PNG:Python实现的高效PPT转图工具 在日常工作中,PPT(PowerPoint)文件是我们常用的演示工具。然而,有时候我们需要将PPT的内容提取为图片格式(如PNG)以便于展示或保存。手动将每一页PPT保…...
TCP和UDP协议
前言 TCP(传输控制协议)和UDP(用户数据报协议)是两种主要的传输层协议;它们在连接方式、可靠性、效率等方面有显著区别。 关键对比 差异总结 可靠性: TCP通过确认应答、重传等机制确保数据可靠传输&#…...
高并发内存池(三):PageCache(页缓存)的实现
前言: 在前两期内容中,我们深入探讨了内存管理机制中在 ThreadCache 和 CentralCache两个层级进行内存申请的具体实现。这两层缓存作为高效的内存分配策略,能够快速响应线程的内存需求,减少锁竞争,提升程序性能。 本期…...
使用pybind11开发可供python使用的c++扩展模块
在做紫微斗数程序的时候用到了padas库,不过也只用了它下面几个功能: 1、读入csv文件,构造DataFrame; 2、通过行列标题查找数据; 3、通过行标题读取一行数据。 用这几个功能却导入了pandas、numpy、dateutil、pytz等一堆库,多少有点划不来,于是想用c++开发一个实现这几…...
系统与网络安全------网络通信原理(5)
资料整理于网络资料、书本资料、AI,仅供个人学习参考。 传输层解析 传输层 传输层的作用 IP层提供点到点的连接传输层提供端到端的连接 端口到端口的连接(不同端口号,代表不同的应用程序) TCP协议概述 TCP(Transm…...
JavaScript防抖与节流
目录 防抖(Debounce) 一、防抖的定义 二、防抖的实现原理 三、防抖的代码实现 四、代码解析 五、使用示例 1. 输入框实时搜索(延迟执行模式) 2. 按钮防重复点击(立即执行模式) 六、总结 节流&…...
Java网络编程实战(多人聊天室-CS模式)
一、C/S模式核心原理 1.1 基本架构 C/S(Client/Server)模式采用客户端-服务器架构: 服务器端:持续运行,负责消息路由和广播客户端:用户交互界面,连接服务器进行通信通信协议:TCP&…...
Vue3.5 + Vite6.x 项目的完整 Stylelint 配置方案,支持 .vue/.html 内联样式、Less/SCSS/CSS 等多种文件类
Vue3.5 Vite6.x 项目的完整 Stylelint 配置方案,支持 .vue/.html 内联样式、Less/SCSS/CSS 等多种文件类型 一、完整依赖安装 npm install --save-dev stylelint stylelint-config-standard postcss-html # 解析 Vue/HTML 文件中的样式postcss-scss …...
23种设计模式Java版(带脑图,带示例源码)
设计模式 1、创建型 1.1、单例模式(Singleton pattern) 确保一个类只有一个实例,并提供该实例的全局访问点。 1.2、工厂方法(Factory Method) 它定义了一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。 1.3、抽象…...
mapbox高阶,使用graphology、graphology-shortest-path前端插件和本地geojson数据纯前端实现路径规划
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️graphology 插件1.3.1 ☘️概念1.3.2 ☘…...
【已解决】vscode升级后连接远程异常:“远程主机可能不符合XXX的先决条件”解决方法
vscode提示升级,每次都升了,突然某次关闭后无法连接远程,查询资料是因为从VS Code 1.86.1版本开始(2024年1月)要求glibc版本>2.28。 命令“ ldd --version”可查看glibc版本为2.27: rootXXXXXXX:~$ ld…...
Springboot整合JAVAFX
Springboot整合JAVAFX 实体与VO设计 pom.xml文件如下: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xs…...
【算法】——一键解决动态规划
前言 动态规划是一种高效解决重叠子问题和最优子结构问题的算法思想。它通过分治记忆化,将复杂问题分解为子问题,并存储中间结果,避免重复计算,从而大幅提升效率。 为什么重要? 优化…...
Git使用与管理
一.基本操作 1.创建本地仓库 在对应文件目录下进行: git init 输入完上面的代码,所在文件目录下就会多一个名为 .git 的隐藏文件,该文件是Git用来跟踪和管理仓库的。 我们可以使用 tree 命令(注意要先下载tree插件)…...
npm、nvm、nrm
NVM (Node Version Manager) 常见指令 NVM 是一个用于管理 Node.js 版本的流行工具,允许你在同一台机器上安装和切换不同版本的 Node.js。以下是 NVM 的常见指令: 安装与卸载 nvm install <version> - 安装指定版本的 Node.js 例如:…...
Java 文件内容转换为MD5哈希值
若要把读取到的 files 列表里的内容转换为 MD5 哈希值,你可以逐个遍历 files 列表中的元素,将每个元素的内容计算成 MD5 哈希值。 以下是一个完整的 Java 示例代码,展示了如何实现这一功能: import java.io.BufferedInputStream…...
未来郴州:科技与自然的交响诗篇
故事背景 故事发生在中国湖南郴州,描绘了未来城市中科技与自然共生共荣的奇妙图景。通过六个充满诗意的场景,展现雾能转化系统、立体生态书库、智能稻田等创新设计,编织出一曲人类智慧与自然韵律共鸣的未来交响。 故事内容 在东江湖的晨雾中&…...
UE5 运行时动态将玩家手部模型设置为相机的子物体
在编辑器里,我们虽然可以手动添加相机,但是无法将网格体设置为相机的子物体,只能将相机设置为网格体的子物体 但是为了使用方便,我们希望将网格体设置为相机的子物体,这样我们直接旋转相机就可以旋转网格体࿰…...
Ubuntu系统下的包管理器APT
Ubuntu系统下的包管理器APT 在Linux操作系统生态中,软件包管理工具是连接用户与系统功能的桥梁。Ubuntu作为基于Debian的流行发行版,其强大的包管理系统APT(Advanced Packaging Tool)为开发者与系统管理员提供了便捷的软件生命周…...
超级码科技发布镂空AI保险胶带,重塑包装防伪新标准
在酒类、物流、奢侈品、电子产品等领域,包装安全与防伪需求日益迫切。传统封箱胶带易被转移或重复利用,导致商品被仿冒的风险居高不下。 为此,超级码科技推出镂空型防揭AI数字身份保险封箱胶带——一款集结构防伪、信息追踪与增值服务于一体的…...
微软Exchange管理中心全球范围宕机
微软已确认Exchange管理中心(Exchange Admin Center,EAC)发生全球性服务中断,导致管理员无法访问关键管理工具。该故障被标记为关键服务事件(编号EX1051697),对依赖Exchange Online的企业造成广…...
前端通信库fetch-event-source实现丰富的SSE
环境:SpringBoot3.4.0 + Vue3 1. 简介 SSE(Server-Sent Events)是一种基于HTTP的服务器向客户端单向推送实时数据的轻量级协议,配合浏览器原生EventSource API,可实现高效实时通信。前端通过创建EventSource对象订阅服务端流,自动处理连接、重试与数据解析;服务端设置C…...
JVM 中Minor GC、Major GC、Full GC 的区别?
Minor GC、Major GC 和 Full GC 是 Java 虚拟机 (JVM) 垃圾回收 (Garbage Collection) 中的不同类型的 GC 事件,它们在范围、触发条件、停顿时间等方面有所不同。 1. Minor GC (Young GC): 范围: 只针对新生代 (Young Generation) 进行垃圾回收。触发条…...
2747. 统计没有收到请求的服务器数目
文章目录 题意思路代码 题意 题目链接 思路 代码 class Solution { public:vector<int> countServers(int n, vector<vector<int>>& logs, int x, vector<int>& queries) {sort(logs.begin(), logs.end(), [](vector<int> &a, v…...
设计模式:抽象工厂 - 掌控多产品族的创建之道
一、什么是抽象工厂模式? 抽象工厂模式是一种创建型设计模式,提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。 核心思想 1.定义多个产品的抽象接口,统一管理具体产品和工厂的创建逻辑。…...
图神经网络+多模态:视频动作分割的轻量高效新解法
一、引言 在智能监控、自动驾驶、人机交互等领域,准确理解视频中的动作序列至关重要。然而,传统方法依赖复杂的视觉模型,计算成本高且难以捕捉长时依赖。近期,一项名为 Semantic2Graph 的研究通过图神经网络(GNN&am…...
技术与情感交织的一生 (五)
目录 初入“江湖” 分工 陌生 CraneOffice 内功 宝典 枪手 回到大二 通关 小聚 唱一首歌 初入“江湖” 分工 软件工作室是坐落在和平区宜昌道的一间民房,和我想象中的公司形象多少有些偏差。天津的道路有点凌乱,初次的时候不太好找…...
简单-快速-高效——模块化解析Pulid(实现不同风格下的人脸一致)
资源 论文:https://arxiv.org/abs/2404.16022 github:https://github.com/ToTheBeginning/PuLID?tabreadme-ov-file comfyui插件:https://github.com/sipie800/ComfyUI-PuLID-Flux-Enhanced 讲解参考 https://zhuanlan.zhihu.com/p/69684…...
XYZ to xyY 求解
免责声明:本文所提供的信息和内容仅供参考。作者对本文内容的准确性、完整性、及时性或适用性不作任何明示或暗示的保证。在任何情况下,作者不对因使用本文内容而导致的任何直接或间接损失承担责任,包括但不限于数据丢失、业务中断或其他经济…...
科技自然的协奏曲-深圳
故事背景 故事发生在中国广东深圳的现代城市环境,这里呈现出未来科技与自然生态共生的独特图景。没有具体的角色,却通过多样的场景描绘,展现出未来生活的活力与创新,反映出社会创新与人类情感的紧密结合。 故事内容 在未来的深…...
idea 创建 maven-scala项目
文章目录 idea 创建 maven-scala项目1、创建普通maven项目并且配置pom.xml文件2、修改项目结构1)创建scala目录并标记成【源目录】2)导入scala环境3)测试环境 idea 创建 maven-scala项目 1、创建普通maven项目并且配置pom.xml文件 maven依赖…...
C++项目:高并发内存池_下
目录 8. thread cache回收内存 9. central cache回收内存 10. page cache回收内存 11. 大于256KB的内存申请和释放 11.1 申请 11.2 释放 12. 使用定长内存池脱离使用new 13. 释放对象时优化成不传对象大小 14. 多线程环境下对比malloc测试 15. 调试和复杂问题的调试技…...
【UE5】RTS游戏的框选功能+行军线效果实现
目录 效果 步骤 一、项目准备 二、框选NPC并移动到指定地点 三、框选效果 四、行军线效果 效果 步骤 一、项目准备 1. 新建一个俯视角游戏工程 2. 新建一个pawn、玩家控制器和游戏模式,这里分别命名为“MyPawn”、“MyController”和“MyGameMode” 3. 打开“MyGam…...
多图超详细:Docker安装知识库AI客服RAGFlow的详细步骤、使用教程及注意事项:
RAGFlow 介绍 RAGFlow 是一款基于深度文档理解的开源检索增强生成(RAG)引擎,通过结合信息检索与生成式 AI 技术,解决复杂场景下的数据处理和可信问答问题。其核心设计目标是提供透明化、可控化的文档处理流程,并通过多…...
docker compose安装智能体平台N8N
使用 docker volume create n8n_data 创建了一个名为 n8n_data 的数据卷。你通过 docker run 启动容器,映射了端口 5678,并挂载了 n8n_data 数据卷。 以下是对应的 docker-compose.yml 配置文件: version: "3.7"services:n8n:ima…...
FRP调用本地摄像头完成远程拍照
from flask import Flask, Response import cv2app Flask(__name__)# 基础文字回复 app.route(/) def hello_world():return <h1>你好啊世界</h1><img src"/camera" width"640" /># 摄像头拍照并返回图像 app.route(/camera) def captu…...
【Linux】39.一个基础的HTTP Web服务器
文章目录 1. 实现一个基础的HTTP Web服务器1.1 功能实现:1.2 Log.hpp-日志记录器1.3 HttpServer.hpp-网页服务器1.4 Socket.hpp-网络通信器1.5 HttpServer.cc-服务器启动器 1. 实现一个基础的HTTP Web服务器 1.1 功能实现: 总体功能: 提供We…...
蓝桥杯-小明的背包(动态规划-Java)
0/1背包问题介绍 0/1背包问题是经典的动态规划问题,具体描述如下: 解题思路: 输入数据 首先,程序通过 Scanner 从输入中读取数据: n 表示物品的数量。 v 表示背包的最大容量。 接着读取每个物品的重量和价值ÿ…...
(四十一)Dart 中的空安全与 `late` 关键字教程
Dart 中的空安全与 late 关键字教程 空安全简介 空安全(Null Safety)是 Dart 语言的一项重要特性,旨在帮助开发者避免空指针异常(NullPointerException)。空安全通过在编译时检查变量是否可能为 null,从而…...
GaussDB使用指南
目录 1. GaussDB 概述 1.1 GaussDB 简介 1.2 核心技术架构 1.3 适用场景与行业案例 2. GaussDB 安装与部署 2.1 环境准备与依赖检查 2.2 单机版安装(Linux) 2.3 分布式集群部署 3. GaussDB 基础操作与语法 3.1 数据库连接与用户管理 3.2 DDL …...
算法训练之动态规划(一)
♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…...
dubbo配置中心
配置中心 简介 配置中心(config-center)在dubbo中可承担两类职责: 外部化配置:启动配置的集中式存储。流量治理规则存储。 Dubbo动态配置中心定义了两个不同层次的隔离选项,分别是namespace和group。 namespace&a…...
移动端六大语言速记:第11部分 - 内存管理
移动端六大语言速记:第11部分 - 内存管理 本文将对比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift这六种移动端开发语言在内存管理方面的特性,帮助开发者理解和掌握各语言的内存管理机制。 11. 内存管理 11.1 垃圾回收机制对比 各语言垃圾回收…...
对象的创建方式有哪些?在虚拟机中具体的创建过程是怎样的?
在Java中,对象的创建方式及其在虚拟机中的具体过程如下: 一、对象的创建方式 使用 new 关键字 最常见的对象创建方式,直接调用类的构造方法。 MyClass obj new MyClass();反射(Reflection) 通过 Class 或 Constructor…...
openwrt软路由配置3
1.启用sftp文件连接 使用ssh连接openwrt时,我发现无法打开sftp windows进行上传和下载文件,提示 sftp channel closed by server: stderr:ash /usr/libexec/sftp-server:not found 原因是系统刚刚装好后,没有安装openssh-sftp-server包 opk…...
C语言for循环嵌套if相关题目
一、题目引入 以下代码程序运行结果是多少? 二、思路解析 进入一个for循环 a<100 进入第一个if b1不大于20为假 进入第二个if b4 a这时a自增为2 当b4时,满足第二个if条件 1.b4,a2 当b7时,满足第二个if条件 2.bb37,a3 当b10时,满足第二个if条件 …...
Redis与Mysql双写一致性如何保证?
我们在面试的时候redis与mysql双写一致性是一个常考的问题,今天我们就一起探讨一下吧 所谓的一致性就是数据的一致性,在分布式系统中,可以理解为多个节点中数据的值是一致的。 强一致性: 这种一致性级别是最符合用户直觉的&…...
STM32 CRC校验与芯片ID应用全解析:从原理到实践 | 零基础入门STM32第九十七步
主题内容教学目的/扩展视频CRC与芯片ID原理实现CRC校验和读取芯片ID为单片机应用提供数据验证和身份识别的功能。 师从洋桃电子,杜洋老师 📑文章目录 一、CRC校验功能解析1.1 CRC基本原理1.2 核心功能对比 二、CRC校验应用实战2.1 典型应用场景2.2 程序实…...
《微服务与事件驱动架构》读书分享
《微服务与事件驱动架构》读书分享 Building Event-Driver Microservices 英文原版由 OReilly Media, Inc. 出版,2020 作者:[加] 亚当 • 贝勒马尔 译者:温正东 作者简介: 这本书由亚当贝勒马尔(Adam Bellemare…...
⼤模型(LLMs)基础
⼤模型(LLMs)基础 ⽬前 主流的开源模型体系 有哪些?prefix Decoder 和 causal Decoder 和 Encoder-Decoder 区别是什么?⼤模型LLM的 训练⽬标 是什么?涌现能⼒是啥原因?为何现在的⼤模型⼤部分是Decoder o…...