How to enumerate the system fonts in the combobox control using VC++ - 用VC++如何在ComboBox控件中枚举系统字体

本文介绍了一个使用C++实现的功能,该功能可以枚举所有可用的字体,并将这些字体名称添加到Windows应用程序的组合框中。通过使用Windows API函数`EnumFontFamilies`和发送`CB_ADDSTRING`消息,实现了字体的枚举与添加。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import os import sys import threading import tkinter as tk from tkinter import filedialog, ttk, messagebox from PIL import Image, ImageOps, ImageFilter class LineArtConverter: def __init__(self, root): self.root = root self.root.title("图片转线稿工具-如影随行开发") self.root.geometry("600x600") self.root.resizable(True, True) # 设置中文字体支持 self.setup_fonts() # 存储要处理的文件路径 self.file_paths = [] # 创建UI self.create_widgets() # 进度相关变量 self.total_files = 0 self.processed_files = 0 def setup_fonts(self): """设置支持中文的字体""" default_font = ('SimHei', 10) self.root.option_add("*Font", default_font) def create_widgets(self): """创建界面组件""" # 创建主框架 main_frame = ttk.Frame(self.root, padding="10") main_frame.pack(fill=tk.BOTH, expand=True) # 标题 title_label = ttk.Label(main_frame, text="图片转线稿工具", font=('SimHei', 16, 'bold')) title_label.pack(pady=10) # 说明文本 desc_label = ttk.Label( main_frame, text="该工具可以将照片转换为线稿风格。支持单张图片或整个文件夹的批量处理。", wraplength=500 ) desc_label.pack(pady=5) # 文件选择按钮区域 select_frame = ttk.Frame(main_frame) select_frame.pack(fill=tk.X, pady=10) import_img_btn = ttk.Button(select_frame, text="导入图片", command=self.import_images) import_img_btn.pack(side=tk.LEFT, padx=5) import_folder_btn = ttk.Button(select_frame, text="导入文件夹", command=self.import_folder) import_folder_btn.pack(side=tk.LEFT, padx=5) # 选择的文件列表 list_frame = ttk.LabelFrame(main_frame, text="已选择的文件", padding="5") list_frame.pack(fill=tk.BOTH, expand=True, pady=10) # 滚动条 scrollbar = ttk.Scrollbar(list_frame) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) # 文件列表 self.file_listbox = tk.Listbox(list_frame, yscrollcommand=scrollbar.set, selectmode=tk.EXTENDED) self.file_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar.config(command=self.file_listbox.yview) # 移除选中文件按钮 remove_btn = ttk.Button(main_frame, text="移除选中文件", command=self.remove_selected) remove_btn.pack(pady=5, anchor=tk.W) # 进度条 self.progress_frame = ttk.LabelFrame(main_frame, text="处理进度", padding="5") self.progress_frame.pack(fill=tk.X, pady=10) self.progress_var = tk.DoubleVar() self.progress_bar = ttk.Progressbar( self.progress_frame, variable=self.progress_var, maximum=100 ) self.progress_bar.pack(fill=tk.X, pady=5) self.progress_label = ttk.Label(self.progress_frame, text="等待开始处理...") self.progress_label.pack(anchor=tk.W) # 按钮区域 btn_frame = ttk.Frame(main_frame) btn_frame.pack(fill=tk.X, pady=10) # 开始处理按钮 self.process_btn = ttk.Button( btn_frame, text="开始转线稿", command=self.start_processing, style='Accent.TButton' ) self.process_btn.pack(side=tk.RIGHT) # 样式设置 style = ttk.Style() style.configure('Accent.TButton', font=('SimHei', 10, 'bold')) def import_images(self): """导入单张或多张图片""" file_types = ( ('图像文件', '*.jpg *.jpeg *.png *.bmp *.gif'), ('所有文件', '*.*') ) filenames = filedialog.askopenfilenames( title="选择图片", initialdir="/", filetypes=file_types ) if filenames: for filename in filenames: if filename not in self.file_paths: self.file_paths.append(filename) self.file_listbox.insert(tk.END, os.path.basename(filename)) def import_folder(self): """导入文件夹""" folder = filedialog.askdirectory(title="选择图片文件夹") if folder: # 获取文件夹中所有图像文件 valid_extensions = ('.jpg', '.jpeg', '.png', '.bmp', '.gif') image_files = [ f for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f)) and f.lower().endswith(valid_extensions) ] if not image_files: messagebox.showinfo("提示", f"在 {folder} 中未找到任何图像文件") return # 添加文件到列表 for file in image_files: file_path = os.path.join(folder, file) if file_path not in self.file_paths: self.file_paths.append(file_path) self.file_listbox.insert(tk.END, file) messagebox.showinfo("提示", f"已添加 {len(image_files)} 个图像文件") def remove_selected(self): """移除选中的文件""" selected_indices = self.file_listbox.curselection() if not selected_indices: return # 从后往前删除,避免索引变化问题 for i in sorted(selected_indices, reverse=True): self.file_listbox.delete(i) del self.file_paths[i] def start_processing(self): """开始处理选中的文件""" if not self.file_paths: messagebox.showwarning("警告", "请先选择要处理的图片或文件夹") return # 禁用处理按钮和文件操作,防止重复处理 self.process_btn.config(state=tk.DISABLED) # 初始化进度 self.total_files = len(self.file_paths) self.processed_files = 0 self.progress_var.set(0) self.progress_label.config(text=f"准备处理 {self.total_files} 个文件...") # 在新线程中处理文件,避免界面卡死 processing_thread = threading.Thread(target=self.process_files) processing_thread.daemon = True processing_thread.start() def update_progress(self, filename, success=True): """更新进度条和状态""" self.processed_files += 1 progress = (self.processed_files / self.total_files) * 100 self.progress_var.set(progress) status = "成功" if success else "失败" self.progress_label.config( text=f"已处理 {self.processed_files}/{self.total_files} 个文件 - {os.path.basename(filename)} {status}" ) # 处理完成后恢复按钮状态 if self.processed_files == self.total_files: self.progress_label.config(text=f"处理完成!共处理 {self.total_files} 个文件") self.process_btn.config(state=tk.NORMAL) messagebox.showinfo("完成", "所有文件处理完成!") def process_files(self): """处理所有选中的文件""" for file_path in self.file_paths: try: # 调用转换函数 result = self.convert_to_line_art(file_path) # 在主线程中更新UI self.root.after(0, self.update_progress, file_path, result is not None) except Exception as e: print(f"处理 {file_path} 时出错: {str(e)}") self.root.after(0, self.update_progress, file_path, False) def convert_to_line_art(self, image_path, radius=2): """ 将照片转换为线稿 参数: image_path: 原始图像路径 radius: 最小值滤镜的半径,默认为2像素 """ try: # 打开原始图像 original = Image.open(image_path).convert('RGB') # 步骤1: 复制图层并去色(图层1) layer1 = original.copy() layer1 = ImageOps.grayscale(layer1) # 去色处理 # 步骤2: 复制图层1创建图层2并反相 layer2 = layer1.copy() layer2 = ImageOps.invert(layer2) # 反相处理 # 步骤3: 对图层2应用最小值滤镜(模拟滤镜-其他-最小值) layer2 = layer2.filter(ImageFilter.MinFilter(size=radius+1)) # size为半径+1 # 步骤4: 将图层2与图层1以线性减淡模式混合 # 实现线性减淡(添加)混合模式: result = min(layer1 + layer2, 255) line_art = Image.new('L', layer1.size) for x in range(layer1.width): for y in range(layer1.height): pixel1 = layer1.getpixel((x, y)) pixel2 = layer2.getpixel((x, y)) blended = min(pixel1 + pixel2, 255) line_art.putpixel((x, y), blended) # 构建输出文件路径 dir_name, file_name = os.path.split(image_path) base_name, ext = os.path.splitext(file_name) output_path = os.path.join(dir_name, f"{base_name}_线稿.jpg") # 保存结果 line_art.save(output_path) return output_path except Exception as e: print(f"处理图像时出错: {str(e)}") return None if __name__ == "__main__": root = tk.Tk() app = LineArtConverter(root) root.mainloop()
07-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值