[Upscayl图像增强] Electron主进程命令 | 进程间通信IPC

第三章:Electron主进程命令

欢迎回来🐻‍❄️

第一章:渲染器用户界面(前端)中,我们探索了您与之交互的按钮和菜单。然后在第二章:AI模型中,我们了解了让您的图像看起来更棒的"智能"。您选择图像,选择模型,然后点击"Upscayl"。

但是在点击按钮和图像实际被放大之间发生了什么 ?谁将您的选择从用户界面转化为计算机上的操作?这就是Electron主进程命令的作用

Electron主进程命令解决了什么问题?

将Upscayl想象成一个繁忙的餐厅。渲染器用户界面(前端)是友好的服务员,接受您的订单("使用'remacri-4x'模型放大这张图像")。

AI模型是专门的食谱。但谁去厨房获取食材,告诉实际的厨师该做什么,并确保一切顺利进行?那就是Electron主进程

Electron主进程命令解决的核心问题是弥合基于web的用户界面与计算机操作系统之间的鸿沟。普通的网页(如前端)不能直接:

  • 在计算机上打开文件选择窗口。
  • 将文件保存到特定文件夹。
  • 运行强大的外部程序。
  • 发送系统通知。

主进程充当整个Upscayl应用程序的"控制中心"或"指挥"。它是Upscayl中唯一能够直接与计算机系统对话的部分,确保应用程序能够执行所有繁重的工作,并与操作系统和其他工具正确交互。

核心用例:协调图像放大

让我们使用主要示例:放大单张图像

当:

  1. 渲染器用户界面(前端)中点击"选择图像"。
  2. 从计算机中选择图像文件。
  3. 选择一个AI模型(如remacri-4x)。
  4. 点击大的"Upscayl"按钮。

Electron主进程协调整个操作。它接收您的指令,准备所有必要的信息,启动实际的放大工作,监控其进度,并处理保存结果。

什么是Electron主进程?

要理解主进程,让我们简要回顾一下Upscayl构建工具Electron。Electron应用程序通常有两种主要类型的进程:

  • 渲染器进程(服务员) :这是渲染器用户界面(前端)所在的地方。它像一个网页浏览器页面,非常适合显示视觉效果和处理点击,但对计算机系统的访问有限。
  • 主进程(厨师/经理):这是应用程序的"大脑"。它运行一个Node.js环境,这意味着它可以完全访问计算机的操作系统。它管理应用程序的窗口,处理系统事件,并执行渲染器进程无法完成的所有"繁重"任务。整个应用程序只有一个主进程。

Electron主进程命令只是渲染器进程发送给主进程的特定指令或"消息",要求它执行系统级任务。

主进程如何与前端通信

由于渲染器和主进程是分开的,它们需要一种相互通信的方式。这是通过**进程间通信(IPC)**实现的。

IPC: https://github.com/lvy010/linux-core/tree/main/ipc_test

想象服务员(前端)将您的订单写在票上并交给厨师(主进程)。票上有清晰的"命令"和所有细节。

在Upscayl中,这些"命令"使用特定名称定义:

typescript 复制代码
// common/electron-commands.ts(简化版)
const ELECTRON_COMMANDS = {
  SELECT_FILE: "选择文件", // 命令主进程打开文件对话框
  UPSCAYL: "放大图像", // 命令主进程开始放大
  UPSCAYL_DONE: "放大完成", // 主进程向前端发送的消息
  UPSCAYL_PROGRESS: "从主进程发送进度到渲染器", // 进度更新
  STOP: "停止当前操作", // 停止放大的命令
  // ... 许多其他命令 ...
} as const;

export { ELECTRON_COMMANDS };

这个ELECTRON_COMMANDS列表就像一个共享字典。渲染器用户界面(前端)和主进程都知道这些名称,确保它们在发送消息时相互理解。

渲染器用户界面(前端)想要完成某件事时,它使用这些命令名称发送消息。当主进程完成任务或有更新时,它使用命令名称向前端发送消息。

放大命令的旅程

让我们追踪当点击"Upscayl"按钮时发生的情况,从用户界面到实际工作完成:

以下是图表的逐步解释:

  1. 用户交互 :您(用户)在渲染器用户界面(前端)中点击"Upscayl"按钮。
  2. 收集信息RendererUI收集您提供的所有信息:原始图像的位置、选择的AI模型、期望的放大倍数(如4x)和其他设置。
  3. 发送命令RendererUI将这些信息打包成"消息",并使用UPSCAYL命令发送给Electron主进程。这条消息包含主进程需要知道的一切。
  4. 主进程准备MainProcess接收UPSCAYL命令。然后执行系统级任务:确定正确的输出文件夹,创建唯一的文件名,并准备运行实际放大程序所需的所有参数。
  5. 启动放大二进制文件MainProcess然后启动一个独立的强大程序,称为放大二进制文件(upscayl-bin)。它将所有准备好的参数(图像路径、模型路径、输出路径、放大倍数等)传递给这个二进制文件。
  6. 放大工作放大二进制文件开始使用选定的AI模型进行实际的、计算密集的图像增强工作。
  7. 进度更新 :当放大二进制文件工作时,它向MainProcess发送进度更新。
  8. 转发进度MainProcess接收这些进度更新,然后使用UPSCAYL_PROGRESS命令将它们发送回RendererUI。这就是看到进度条移动的方式!
  9. 完成 :一旦放大二进制文件完成,它告诉MainProcess它已完成,并提供新放大图像的路径。
  10. 最终通知和显示MainProcess发送最终的UPSCAYL_DONE命令,包括放大图像的路径,返回给RendererUIRendererUI然后显示惊人的结果,并可能向您显示系统通知。

这整个序列由主进程协调,充当中央指挥。

深入代码:如何处理命令

让我们看一些简化的代码片段,看看这些命令在Upscayl中是如何实际注册和处理的

1. 在主进程中注册命令

主进程需要知道当接收到特定命令时该做什么

这就像餐厅经理将任务分配给员工。在Electron中,这是使用ipcMain.on(对于仅执行操作的命令)或ipcMain.handle(对于返回值的命令)完成的。

typescript 复制代码
// electron/index.ts(简化版)
import { app, ipcMain } from "electron";
import { ELECTRON_COMMANDS } from "../common/electron-commands";
import selectFile from "./commands/select-file"; // 选择文件的命令处理程序
import imageUpscayl from "./commands/image-upscayl"; // 放大命令的处理程序
import stop from "./commands/stop"; // 停止任务的命令处理程序

app.on("ready", async () => {
  // ... 其他应用程序设置 ...

  // 注册命令:当前端发送SELECT_FILE时,运行'selectFile'函数
  ipcMain.handle(ELECTRON_COMMANDS.SELECT_FILE, selectFile);

  // 注册命令:当前端发送UPSCAYL时,运行'imageUpscayl'函数
  ipcMain.on(ELECTRON_COMMANDS.UPSCAYL, imageUpscayl);

  // 注册命令:当前端发送STOP时,运行'stop'函数
  ipcMain.on(ELECTRON_COMMANDS.STOP, stop);
});

这个electron/index.ts文件是主进程的入口点。它是应用程序开始监听来自渲染器用户界面(前端)的所有不同命令的地方。每个ipcMain.handleipcMain.on行将一个特定的ELECTRON_COMMANDS消息连接到一个将处理它的函数(如selectFileimageUpscayl)。

2. 处理"选择文件"命令

当您在渲染器用户界面(前端)中点击"选择图像"时,该组件发送一个SELECT_FILE命令。以下是主进程接收它时的操作:

typescript 复制代码
// electron/commands/select-file.ts(简化版)
import { dialog } from "electron";
import { setSavedImagePath } from "../utils/config-variables";
import logit from "../utils/logit"; // 记录消息的辅助工具

const selectFile = async () => {
  // 在计算机上打开一个本地文件选择对话框
  const { canceled, filePaths } = await dialog.showOpenDialog({
    properties: ["openFile"],
    title: "选择图像",
    filters: [{ name: "图像", extensions: ["png", "jpg", "jpeg"] }],
  });

  if (canceled) {
    logit("🚫 文件选择已取消");
    return null; // 如果用户取消,返回null
  } else {
    setSavedImagePath(filePaths[0]); // 保存路径以备下次使用
    logit("📄 选择的文件路径: ", filePaths[0]);
    return filePaths[0]; // 将选择的文件路径发送回前端
  }
};

export default selectFile;

这个selectFile函数非常重要,因为它允许Upscayl与计算机的文件系统交互。当这个函数运行时,它使用dialog.showOpenDialog显示熟悉的"打开文件"窗口。如果您选择一个文件,它的路径(如C:/Users/您的名字/图片/image.jpg)将返回给渲染器用户界面(前端),然后显示图像。

3. 处理"放大图像"命令

这是最重要的一个!当发送UPSCAYL命令时,主进程中的imageUpscayl函数接管:

typescript 复制代码
// electron/commands/image-upscayl.ts(简化版)
import { modelsPath } from "../utils/get-resource-paths"; // 内置AI模型的路径
import { ELECTRON_COMMANDS } from "../../common/electron-commands";
import { setChildProcesses } from "../utils/config-variables";
import { getSingleImageArguments } from "../utils/get-arguments"; // 构建参数的辅助工具
import { spawnUpscayl } from "../utils/spawn-upscayl"; // 运行放大程序的辅助工具
import { getMainWindow } from "../main-window";
import logit from "../utils/logit";

const imageUpscayl = async (event, payload) => {
  const mainWindow = getMainWindow(); // 获取主窗口的引用
  if (!mainWindow) return;

  // 从前端传递的payload中提取所有设置
  const model = payload.model;
  const imagePath = payload.imagePath;
  const outputPath = payload.outputPath;
  const scale = payload.scale;
  // ... 以及payload中的许多其他设置 ...

  // 为放大二进制文件构建特定的命令行参数
  const args = getSingleImageArguments({
    inputDir: imagePath,
    model: model,
    modelsPath: modelsPath, // 提供AI模型文件的路径
    outFile: outputPath,
    scale: scale,
    // ... 所有其他参数 ...
  });

  // 启动实际的放大程序([放大二进制文件(`upscayl-bin`)])
  const upscaylProcess = spawnUpscayl(args, logit);
  setChildProcesses(upscaylProcess); // 跟踪这个正在运行的进程

  // 监听放大二进制文件的进度更新
  upscaylProcess.process.stderr.on("data", (data: string) => {
    // 将进度百分比发送回前端
    mainWindow.webContents.send(
      ELECTRON_COMMANDS.UPSCAYL_PROGRESS,
      data.toString(),
    );
  });

  // 监听放大程序何时完成
  upscaylProcess.process.on("close", async () => {
    logit("💯 放大完成");
    // 通知前端放大已完成
    mainWindow.webContents.send(
      ELECTRON_COMMANDS.UPSCAYL_DONE,
      outputPath,
    );
    // ... 执行最终任务,如显示通知 ...
  });
};

export default imageUpscayl;

这个imageUpscayl函数是放大过程的终极"指挥"!

  1. 它接收payload(来自渲染器用户界面(前端)的所有选择的集合)。
  2. 然后使用辅助函数(getSingleImageArguments)构建外部放大二进制文件(upscayl-bin)运行所需的精确命令。
  3. spawnUpscayl函数然后执行放大二进制文件(upscayl-bin)作为一个独立的程序。
  4. 关键的是,它为这个运行的程序附加"监听器"(.on("data").on("close"))。这使得MainProcess能够持续监控进度,并确切知道放大何时完成。
  5. 然后它将这些更新转发回渲染器用户界面(前端),使用UPSCAYL_PROGRESSUPSCAYL_DONE等命令。

结论

Electron主进程命令是将在渲染器用户界面(前端)中的交互与计算机的系统级操作连接起来的重要纽带。

它充当"控制中心",解释意愿,协调复杂的任务(如文件操作和运行外部程序),并将反馈传递给您。没有这个关键组件,Upscayl无法在桌面上执行任何核心功能

现在我们已经了解了谁下达命令,在下一章中,我们将深入探讨实际执行繁重工作的组件:放大二进制文件(upscayl-bin),这是Upscayl魔力背后的力量

相关推荐
THMAIL6 小时前
机器学习从入门到精通 - 循环神经网络(RNN)与LSTM:时序数据预测圣经
人工智能·python·rnn·算法·机器学习·逻辑回归·lstm
AIbase20246 小时前
AI时代企业获取精准流量与实现增长的GEO新引擎
人工智能·搜索引擎·百度
陈敬雷-充电了么-CEO兼CTO6 小时前
具身智能模拟器:解决机器人实机训练场景局限与成本问题的创新方案
大数据·人工智能·机器学习·chatgpt·机器人·具身智能
东临碣石826 小时前
【AI论文】Robix:一种面向机器人交互、推理与规划的统一模型
人工智能
Hello Mr.Z6 小时前
使用pytorch创建/训练/推理OCR模型
人工智能·pytorch·python
wan5555cn7 小时前
文字生视频的“精准”代码设定的核心原则本质是最小化文本语义与视频内容的KL散度
人工智能·笔记·深度学习·音视频
IT_陈寒7 小时前
Python异步编程的7个致命误区:90%开发者踩过的坑及高效解决方案
前端·人工智能·后端
老猿讲编程7 小时前
存算一体:重构AI计算的革命性技术(1)
人工智能·重构
easy20207 小时前
从 Excel 趋势线到机器学习:拆解 AI 背后的核心框架
人工智能·笔记·机器学习