<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://blog.levek.top/</id>
  <title type="text">levek</title>
  <subtitle type="text">Blog</subtitle>
  <updated>2026-10-17T00:00:00.000Z</updated>
  <author><name>levek</name></author>
  <link rel="alternate" href="https://blog.levek.top/"/>
  <link rel="self" href="https://blog.levek.top/atom.xml"/>
  <generator uri="https://github.com/CuteLeaf/Firefly">Firefly v6.16.8</generator>
    <entry>
      <id>https://blog.levek.top/posts/vm/vmware%E5%AE%89%E8%A3%85ubuntu2204/</id>
      <title type="text">VMware 安装 Ubuntu 22.04 教程</title>
      <published>2026-10-17T00:00:00.000Z</published>
      <updated>2026-10-17T00:00:00.000Z</updated>
      <author><name>levek</name></author>
      <link rel="alternate" href="https://blog.levek.top/posts/vm/vmware%E5%AE%89%E8%A3%85ubuntu2204/"/>
      <summary type="text">VMware 虚拟机安装 Ubuntu 22.04 LTS 图文教程：ISO 下载、新建虚拟机、系统安装到 VMware Tools 与换源优化全程演示，零基础也能顺利装好 Linux～</summary>
      <content type="html"><![CDATA[<section><h2>📥 系统下载<a href="#-系统下载"><span>#</span></a></h2>

<table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>系统名称</td><td>Ubuntu 22.04 LTS（Jammy Jellyfish）</td></tr><tr><td>镜像大小</td><td>约 4.7 GB（desktop 桌面版 ISO）</td></tr><tr><td>运行环境</td><td>已安装 VMware Workstation 的 Win 10 / Win 11</td></tr></tbody></table><ul>
<li><strong>[官网下载链接]</strong>：<a href="https://ubuntu.com/download/desktop" target="_blank">https://ubuntu.com/download/desktop</a></li>
<li><strong>[清华大学镜像站]</strong>：<a href="https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/22.04/" target="_blank">https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/22.04/</a>（国内下载更快，选择 <code>ubuntu-22.04.5-desktop-amd64.iso</code> 即可）</li>
</ul><blockquote><p>💡 还没安装 VMware？先看上一篇 <a href="/posts/VM/Windows%E5%AE%89%E8%A3%85VMware%E8%99%9A%E6%8B%9F%E6%9C%BA/">VMware 17.6 安装教程（Windows）</a> 装好虚拟机软件，再回来继续。</p></blockquote><hr /></section>
<section><h2>📖 系统介绍<a href="#-系统介绍"><span>#</span></a></h2><p>Ubuntu 是最流行的 Linux 桌面发行版之一，22.04 是长期支持（LTS）版本，官方维护到 2027 年，稳定、免费、软件生态丰富。借助 VMware 虚拟机，可以在不破坏 Windows 系统的前提下安装体验 Ubuntu，非常适合学习 Linux 命令、搭建开发环境、测试软件。</p><hr /></section>
<section><h2>🛠️ 安装步骤<a href="#️-安装步骤"><span>#</span></a></h2><section><h3>一、新建虚拟机<a href="#一新建虚拟机"><span>#</span></a></h3><p>打开 VMware，点击「<strong>文件 → 新建虚拟机</strong>」（或主页上的「创建新的虚拟机」），选择「<strong>典型（推荐）</strong>」，点击「<strong>下一步</strong>」。</p><p>安装来源选择「<strong>稍后安装操作系统</strong>」，点击「<strong>下一步</strong>」。</p><blockquote><p>💡 直接选 ISO 镜像会触发 VMware 的「简易安装」，自动跳过部分设置项，新手容易装出意外的账号配置，建议稍后手动挂载镜像。</p></blockquote><p>客户机操作系统选择「<strong>Linux</strong>」，版本选择「<strong>Ubuntu 64 位</strong>」，点击「<strong>下一步</strong>」。</p><p>给虚拟机起个名字（如 <code>Ubuntu22.04</code>），并选择一个<strong>剩余空间充足</strong>的安装位置（虚拟机文件较大，建议放在非系统盘），点击「<strong>下一步</strong>」。</p><p>磁盘容量按需求填写，建议 <strong>40 GB 以上</strong>，选择「<strong>将虚拟磁盘拆分成多个文件</strong>」，点击「<strong>下一步</strong>」。</p><p>点击「<strong>自定义硬件</strong>」，按下面的建议调整配置：</p>

<table><thead><tr><th>硬件</th><th>建议配置</th></tr></thead><tbody><tr><td>内存</td><td>4 GB 起步，建议 8 GB（宿主机 16GB 以上）</td></tr><tr><td>处理器</td><td>2 核起步，建议 4 核</td></tr><tr><td>网络适配器</td><td>NAT 模式（虚拟机可直接共享宿主机上网）</td></tr><tr><td>CD/DVD</td><td>使用 ISO 映像文件，选择刚下载的 Ubuntu 镜像</td></tr></tbody></table><p>设置完成后关闭硬件窗口，点击「<strong>完成</strong>」，虚拟机就创建好了。</p></section><section><h3>二、安装 Ubuntu 系统<a href="#二安装-ubuntu-系统"><span>#</span></a></h3><p>选中刚创建的虚拟机，点击「<strong>开启此虚拟机</strong>」。VMware 窗口里出现 Ubuntu 启动画面后，用键盘方向键选择「<strong>Install Ubuntu</strong>」（也可以先选 Try Ubuntu 体验再安装），回车。</p><p>安装过程中按提示依次进行：</p><p><strong>1.</strong> 语言选择「<strong>中文（简体）</strong>」，点击「<strong>安装 Ubuntu</strong>」。</p><p><strong>2.</strong> 键盘布局保持默认的「<strong>汉语</strong>」即可，点击「<strong>继续</strong>」。</p><p><strong>3.</strong> 选择「<strong>正常安装</strong>」，并勾选「<strong>为图形或无线硬件以及其他媒体格式安装第三方软件</strong>」，点击「<strong>继续</strong>」。</p><blockquote><p>💡 只是想体验一下或磁盘紧张，可以选「最小安装」，占用更小、更干净。</p></blockquote><p><strong>4.</strong> 安装类型选择「<strong>清除整个磁盘并安装 Ubuntu</strong>」，点击「<strong>现在安装</strong>」，弹出确认窗口后点击「<strong>继续</strong>」。</p><blockquote><p>💡 这里的「磁盘」指的是虚拟机分配的那 40 GB 虚拟磁盘，<strong>不会</strong>动到你电脑真实的硬盘和 Windows 系统，放心操作。</p></blockquote><p><strong>5.</strong> 地图上点选或输入「<strong>Shanghai</strong>」（时区），点击「<strong>继续</strong>」。</p><p><strong>6.</strong> 填写你的姓名、计算机名、用户名和密码，选择「<strong>登录时需要密码</strong>」，点击「<strong>继续</strong>」。</p><p>接下来就是等待安装，进度条走完后点击「<strong>现在重启</strong>」。看到提示 <code>Please remove the installation medium, then press ENTER</code> 时，直接按<strong>回车</strong>即可（VMware 会自动断开 ISO 镜像）。</p></section><section><h3>三、安装 VMware Tools<a href="#三安装-vmware-tools"><span>#</span></a></h3><p>装好系统后先装 VMware Tools，才能实现<strong>全屏自适应分辨率、Windows 与虚拟机之间复制粘贴、拖拽文件</strong>等功能。</p><p>在 Ubuntu 里打开终端（快捷键 <code>Ctrl + Alt + T</code>），依次执行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>update</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>open-vm-tools</span><span> </span><span>open-vm-tools-desktop</span></div></div><div><div><div>3</div></div><div><span>sudo</span><span> </span><span>reboot</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>重启后把 VMware 窗口拉大，Ubuntu 分辨率会自动跟着变；此时从 Windows 复制一段文字，直接在 Ubuntu 里粘贴即可。</p><hr /></section></section>
<section><h2>🚀 装机后优化（可选）<a href="#-装机后优化可选"><span>#</span></a></h2><section><h3>1. 更新系统软件<a href="#1-更新系统软件"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>update</span><span> &amp;&amp; </span><span>sudo</span><span> </span><span>apt</span><span> </span><span>upgrade</span><span> </span><span>-y</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2. 更换国内软件源（推荐）<a href="#2-更换国内软件源推荐"><span>#</span></a></h3><p>Ubuntu 默认官方源在国内速度较慢，换成清华源后下载速度会快很多。先备份原文件，再替换内容：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>cp</span><span> </span><span>/etc/apt/sources.list</span><span> </span><span>/etc/apt/sources.list.bak</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>sed</span><span> </span><span>-i</span><span> </span><span>'s@//.*archive.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g'</span><span> </span><span>/etc/apt/sources.list</span></div></div><div><div><div>3</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>update</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section>
<section><h2>❓ 常见问题<a href="#-常见问题"><span>#</span></a></h2>

<table><thead><tr><th>问题</th><th>解决办法</th></tr></thead><tbody><tr><td>开启虚拟机提示 <code>Intel VT-x 处于禁用状态</code></td><td>重启电脑进 BIOS/UEFI，开启 <code>Intel VT-x</code>（或 <code>SVM Mode</code>）虚拟化支持</td></tr><tr><td>安装时分辨率太低、界面显示不全</td><td>按住 <code>Super</code>（Win 键）拖动窗口，或先选 Try Ubuntu 体验模式调整分辨率</td></tr><tr><td>虚拟机里上不了网</td><td>确认网络适配器为 NAT 模式；仍不行就在 Ubuntu 终端执行 <code>sudo systemctl restart NetworkManager</code></td></tr><tr><td>Windows 与虚拟机无法复制粘贴</td><td>确认已安装 <code>open-vm-tools-desktop</code> 并重启过虚拟机</td></tr></tbody></table><hr /></section>
<section><h2>✅ 安装完成！<a href="#-安装完成"><span>#</span></a></h2><p>恭喜，你已经拥有了一台属于自己的 Ubuntu 22.04 虚拟机 🎉</p><section><h3>本网站提供的所有教程仅供学习使用，无任何商务用途!<a href="#本网站提供的所有教程仅供学习使用无任何商务用途"><span>#</span></a></h3></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.levek.top/posts/x2_sim_docker/x2%E8%99%9A%E6%8B%9F%E4%BB%BF%E7%9C%9Fdocker%E9%83%A8%E7%BD%B2/</id>
      <title type="text">灵犀 X2 虚拟仿真空间部署（Docker）</title>
      <published>2026-10-17T00:00:00.000Z</published>
      <updated>2026-10-17T00:00:00.000Z</updated>
      <author><name>levek</name></author>
      <link rel="alternate" href="https://blog.levek.top/posts/x2_sim_docker/x2%E8%99%9A%E6%8B%9F%E4%BB%BF%E7%9C%9Fdocker%E9%83%A8%E7%BD%B2/"/>
      <summary type="text">灵犀 X2 人形机器人 MuJoCo 虚拟仿真空间 Docker 部署全流程：镜像构建、容器启动、aimdk 与运控栈编译、onnxruntime 依赖、CycloneDDS 与符号问题排障，直到仿真与运控通信打通。</summary>
      <content type="html"><![CDATA[<p>本文记录在一台 x86_64 Ubuntu 机器上，用 Docker 部署灵犀 X2 的 MuJoCo 虚拟仿真空间，从镜像构建到仿真与运动控制器（MC）通信打通的完整过程。</p>
<section><h2>参考<a href="#参考"><span>#</span></a></h2><p><a href="https://x2-aimdk.agibot.com/zh-cn/latest/" target="_blank">智元机器人灵犀 X2 AimDK 文档</a>
<a href="https://docs.ros.org/en/humble/index.html" target="_blank">ROS 2 Humble 文档</a></p></section>
<section><h2>1. 环境要求<a href="#1-环境要求"><span>#</span></a></h2>

<table><thead><tr><th>项目</th><th>要求</th></tr></thead><tbody><tr><td>电脑</td><td>x86_64，建议 16 GB 或以上内存（实测 8 GB 偏紧，容易卡死）</td></tr><tr><td>系统</td><td>Ubuntu 22.04 或 24.04，带图形桌面</td></tr><tr><td>软件</td><td>Docker（宿主机无需安装 ROS 2）</td></tr><tr><td>GPU</td><td>可选，无独显也能跑（默认走核显/软件渲染）</td></tr><tr><td>网络</td><td>首次部署需下载基础镜像和软件包</td></tr></tbody></table><p>先在宿主机确认 X11 转发工具已装：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>if</span><span> ! </span><span>command</span><span> </span><span>-v</span><span> </span><span>xhost</span><span> &gt;</span><span>/dev/null</span><span> 2&gt;&amp;1; </span><span>then</span></div></div><div><div><div>2</div></div><div><span>  </span><span>sudo</span><span> </span><span>apt</span><span> </span><span>update</span></div></div><div><div><div>3</div></div><div><span>  </span><span>sudo</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>x11-xserver-utils</span></div></div><div><div><div>4</div></div><div><span>fi</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>2. 准备软件目录<a href="#2-准备软件目录"><span>#</span></a></h2><p>把交付文件放到同一工作目录，目录名可自定，下面以 <code>x2_simulation/</code> 为例：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>x2_simulation/</span></div></div><div><div><div>2</div></div><div><span>├── aimdk/                  # SDK 源码（aimdk_msgs、py_examples、examples、robotop、ruckig）</span></div></div><div><div><div>3</div></div><div><span>├── x2_rl_deploy/           # 官方 MuJoCo 仿真 + 运控扩展包</span></div></div><div><div><div>4</div></div><div><span>│   ├── aimdk_msgs/         # 含 ProcessInfo 的完整消息集</span></div></div><div><div><div>5</div></div><div><span>│   ├── x2_rl_deploy_controller/   # 运动控制器（MC）</span></div></div><div><div><div>6</div></div><div><span>│   ├── x2_rl_deploy_mujoco/       # MuJoCo 仿真（HAL 层）</span></div></div><div><div><div>7</div></div><div><span>│   └── third_party/onnxruntime-linux-x64-1.23.2/   # RL 策略推理依赖</span></div></div><div><div><div>8</div></div><div><span>├── sim_mujoco/             # 指向 x2_rl_deploy/x2_rl_deploy_mujoco</span></div></div><div><div><div>9</div></div><div><span>├── Dockerfile</span></div></div><div><div><div>10</div></div><div><span>└── run_docker.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>控制链路：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>SDK(py_examples) ──高层指令──&gt; MC(x2_rl_deploy_controller) ──关节命令──&gt; sim_mujoco</span></div></div><div><div><div>2</div></div><div><span><span>                                  </span></span><span>^                                      │</span></div></div><div><div><div>3</div></div><div><span><span>                                  </span></span><span>└────── 关节与 IMU 状态回传 &lt;───────────┘</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>3. 构建镜像<a href="#3-构建镜像"><span>#</span></a></h2><p>工作目录下的 <code>Dockerfile</code> 以 ROS 2 Humble 官方镜像为基础，装齐编译和运行依赖：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>FROM</span><span> osrf/ros:humble-desktop-full</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>ENV</span><span> DEBIAN_FRONTEND=noninteractive</span></div></div><div><div><div>4</div></div><div><span>ENV</span><span> RMW_IMPLEMENTATION=rmw_fastrtps_cpp</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>RUN</span><span> apt-get update &amp;&amp; apt-get install -y --no-install-recommends \</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>build-essential ca-certificates cmake curl \</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>libcurl4-openssl-dev libeigen3-dev libgflags-dev \</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>libgl1 libgl1-mesa-dri libglx-mesa0 libncurses-dev \</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>liboctomap1.9 libopencv-dev libscrypt0 libyaml-cpp-dev \</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>mesa-utils pkg-config python3-colcon-common-extensions python3-pip \</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>ros-humble-cv-bridge ros-humble-grid-map-msgs ros-humble-grid-map-ros \</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>ros-humble-joy ros-humble-rmw-fastrtps-cpp \</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>&amp;&amp; rm -rf /var/lib/apt/lists/*</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>RUN</span><span> printf </span><span>'%s</span><span>\n</span><span>'</span><span> \</span></div></div><div><div><div>17</div></div><div><span>      </span><span>'source /opt/ros/humble/setup.bash'</span><span> \</span></div></div><div><div><div>18</div></div><div><span>      </span><span>'export RMW_IMPLEMENTATION=rmw_fastrtps_cpp'</span><span> \</span></div></div><div><div><div>19</div></div><div><span>      </span><span>'if [ -f /workspace/aimdk/install/local_setup.bash ]; then source /workspace/aimdk/install/local_setup.bash; fi'</span><span> \</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>&gt;&gt; /root/.bashrc</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>WORKDIR</span><span> /workspace</span></div></div><div><div><div>23</div></div><div><span>CMD</span><span> [</span><span>"bash"</span><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>国内网络建议先配 Docker 镜像加速，再拉基础镜像：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/etc/docker</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>cp</span><span> </span><span>/etc/docker/daemon.json</span><span> </span><span>/etc/docker/daemon.json.bak</span><span> 2&gt;</span><span>/dev/null</span><span> || </span><span>true</span></div></div><div><div><div>3</div></div><div><span>echo</span><span> </span><span>'{"registry-mirrors":["https://docker.m.daocloud.io","https://docker.1ms.run"]}'</span><span> | </span><span>sudo</span><span> </span><span>tee</span><span> </span><span>/etc/docker/daemon.json</span><span> &gt;</span><span>/dev/null</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>systemctl</span><span> </span><span>restart</span><span> </span><span>docker</span></div></div><div><div><div>5</div></div><div><span>docker</span><span> </span><span>pull</span><span> </span><span>osrf/ros:humble-desktop-full</span></div></div><div><div><div>6</div></div><div><span>docker</span><span> </span><span>build</span><span> </span><span>-t</span><span> </span><span>x2-simulation:latest</span><span> </span><span>.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>目标架构是 x86_64，如果镜像文件名带 aarch64 说明是 ARM 包，不能用。编译产物不能跨架构混用。</p></blockquote></section>
<section><h2>4. 启动容器<a href="#4-启动容器"><span>#</span></a></h2><p><code>run_docker.sh</code> 负责挂载工作目录、转发 X11 显示、并把宿主机 <code>/agibot</code> 挂进容器（MC 运行时目录）：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/usr/bin/env bash</span></div></div><div><div><div>2</div></div><div><span>set</span><span> </span><span>-euo</span><span> </span><span>pipefail</span></div></div><div><div><div>3</div></div><div><span>ROOT_DIR</span><span><span>=</span><span>$(</span></span><span>cd</span><span> </span><span>"$(</span><span>dirname</span><span> "</span><span><span>${</span><span>BASH_SOURCE</span></span><span>[0]</span><span>}</span><span>")"</span><span> &amp;&amp; </span><span>pwd</span><span>)</span></div></div><div><div><div>4</div></div><div><span>IMAGE_NAME</span><span>=</span><span>x2-simulation:latest</span></div></div><div><div><div>5</div></div><div><span>CONTAINER_NAME</span><span>=</span><span>x2-sim</span></div></div><div><div><div>6</div></div><div><span>xhost</span><span> </span><span>+si:localuser:root</span><span> &gt;</span><span>/dev/null</span><span> 2&gt;&amp;1 || </span><span>true</span></div></div><div><div><div>7</div></div><div><span>docker</span><span> </span><span>rm</span><span> </span><span>-f</span><span> </span><span>"</span><span><span>${</span><span>CONTAINER_NAME</span><span>}</span></span><span>"</span><span> &gt;</span><span>/dev/null</span><span> 2&gt;&amp;1 || </span><span>true</span></div></div><div><div><div>8</div></div><div><span>DOCKER_ARGS</span><span><span>=</span><span>(</span></span></div></div><div><div><div>9</div></div><div><span>  </span><span>run</span><span> </span><span>-it</span></div></div><div><div><div>10</div></div><div><span>  </span><span>--name</span><span> </span><span>"</span><span><span>${</span><span>CONTAINER_NAME</span><span>}</span></span><span>"</span></div></div><div><div><div>11</div></div><div><span>  </span><span>--network</span><span> </span><span>host</span></div></div><div><div><div>12</div></div><div><span>  </span><span>--ipc</span><span> </span><span>host</span></div></div><div><div><div>13</div></div><div><span>  </span><span>-e</span><span> </span><span>"DISPLAY=</span><span><span>${</span><span>DISPLAY</span></span><span>:-:</span><span><span>0</span><span>}</span></span><span>"</span></div></div><div><div><div>14</div></div><div><span>  </span><span>-e</span><span> </span><span>QT_X11_NO_MITSHM</span><span>=</span><span>1</span></div></div><div><div><div>15</div></div><div><span>  </span><span>-e</span><span> </span><span>RMW_IMPLEMENTATION</span><span>=</span><span>rmw_fastrtps_cpp</span></div></div><div><div><div>16</div></div><div><span>  </span><span>-v</span><span> </span><span>"</span><span><span>${</span><span>ROOT_DIR</span><span>}</span></span><span>/aimdk:/workspace/aimdk:rw"</span></div></div><div><div><div>17</div></div><div><span>  </span><span>-v</span><span> </span><span>"</span><span><span>${</span><span>ROOT_DIR</span><span>}</span></span><span>/sim_mujoco:/workspace/sim_mujoco:rw"</span></div></div><div><div><div>18</div></div><div><span>  </span><span>-v</span><span> </span><span>"</span><span><span>${</span><span>ROOT_DIR</span><span>}</span></span><span>/x2_rl_deploy:/workspace/x2_rl_deploy:rw"</span></div></div><div><div><div>19</div></div><div><span>  </span><span>-v</span><span> </span><span>/agibot:/agibot:rw</span></div></div><div><div><div>20</div></div><div><span>  </span><span>-v</span><span> </span><span>/tmp/.X11-unix:/tmp/.X11-unix:rw</span></div></div><div><div><div>21</div></div><div><span>  </span><span>-w</span><span> </span><span>/workspace</span></div></div><div><div><div>22</div></div><div><span>)</span></div></div><div><div><div>23</div></div><div><span>if</span><span><span> [[ </span><span>-d</span><span> /dev/dri ]]; </span></span><span>then</span></div></div><div><div><div>24</div></div><div><span>  </span><span>DOCKER_ARGS</span><span><span>+=</span><span>(</span></span><span>--device</span><span> </span><span>/dev/dri</span><span>)</span></div></div><div><div><div>25</div></div><div><span>fi</span></div></div><div><div><div>26</div></div><div><span>docker</span><span> </span><span>"</span><span><span>${</span><span>DOCKER_ARGS</span></span><span>[</span><span>@</span><span>]</span><span>}</span><span>"</span><span> </span><span>"</span><span><span>${</span><span>IMAGE_NAME</span><span>}</span></span><span>"</span><span> </span><span>bash</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>宿主机准备好 MC 运行时目录，然后执行脚本：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/agibot/data/var/</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>chown</span><span> </span><span>"</span><span>$USER</span><span>:</span><span>$USER</span><span>"</span><span> </span><span>-R</span><span> </span><span>/agibot</span></div></div><div><div><div>3</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>run_docker.sh</span></div></div><div><div><div>4</div></div><div><span>./run_docker.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行后进入容器，这个终端作为后续的「终端 1」。要后台常驻（不占用交互终端）可用：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>exec</span><span> </span><span>-d</span><span> </span><span>x2-sim</span><span> </span><span>bash</span><span> </span><span>/workspace/x2_rl_deploy/start_simulation_stack.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>5. 编译 SDK 与运控栈<a href="#5-编译-sdk-与运控栈"><span>#</span></a></h2><p>容器内先编译 aimdk：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/workspace/aimdk</span></div></div><div><div><div>2</div></div><div><span>source</span><span> </span><span>/opt/ros/humble/setup.bash</span></div></div><div><div><div>3</div></div><div><span>colcon</span><span> </span><span>build</span></div></div><div><div><div>4</div></div><div><span>source</span><span> </span><span>install/local_setup.bash</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>再编译 x2_rl_deploy（运控 + 消息）。编译前需要给 <code>x2_rl_deploy_controller</code> 准备 onnxruntime（见第 6 节）。</p></section>
<section><h2>6. 准备 onnxruntime 依赖<a href="#6-准备-onnxruntime-依赖"><span>#</span></a></h2><p><code>x2_rl_deploy_controller</code> 用 ONNX 推理 RL 策略，CMake 里 <code>find_package(onnxruntime REQUIRED)</code>。容器内没有安装 onnxruntime，也没有 root 权限装到系统目录，解决办法是下载官方预编译包放到 <code>third_party/</code>，并让 CMake 用这个本地路径。</p><p>下载并解压（宿主机或容器内均可）：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/workspace/x2_rl_deploy</span></div></div><div><div><div>2</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>third_party</span></div></div><div><div><div>3</div></div><div><span>curl</span><span> </span><span>-L</span><span> </span><span>https://github.com/microsoft/onnxruntime/releases/download/v1.23.2/onnxruntime-linux-x64-1.23.2.tgz</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-o</span><span> </span><span>third_party/onnxruntime.tgz</span></div></div><div><div><div>5</div></div><div><span>tar</span><span> </span><span>-xzf</span><span> </span><span>third_party/onnxruntime.tgz</span><span> </span><span>-C</span><span> </span><span>third_party</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>按 CMake 目标里约定的目录补全 <code>lib64</code> 和头文件布局：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>third_party/onnxruntime-linux-x64-1.23.2</span></div></div><div><div><div>2</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>lib64</span><span> </span><span>include/onnxruntime</span></div></div><div><div><div>3</div></div><div><span>cp</span><span> </span><span>-a</span><span> </span><span>lib/</span><span>*</span><span>.so</span><span>*</span><span> </span><span>lib64/</span></div></div><div><div><div>4</div></div><div><span>cp</span><span> </span><span>-a</span><span> </span><span>include/</span><span>*</span><span>.h</span><span> </span><span>include/onnxruntime/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后把 <code>x2_rl_deploy_controller/CMakeLists.txt</code> 里的 <code>find_package(onnxruntime REQUIRED)</code> 改成指向本地目录：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>set</span><span>(ONNXRUNTIME_DIR </span><span>"${CMAKE_CURRENT_SOURCE_DIR}/../third_party/onnxruntime-linux-x64-1.23.2"</span><span>)</span></div></div><div><div><div>2</div></div><div><span>find_package</span><span>(onnxruntime REQUIRED</span></div></div><div><div><div>3</div></div><div><span>  </span><span>PATHS</span><span> </span><span>"${ONNXRUNTIME_DIR}/lib/cmake/onnxruntime"</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>NO_DEFAULT_PATH</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>HINTS </span><span>"${ONNXRUNTIME_DIR}"</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>并在 <code>target_include_directories</code> 里加上 <code>${ONNXRUNTIME_DIR}/include</code>。</p><p>改好后编译：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/workspace/x2_rl_deploy</span></div></div><div><div><div>2</div></div><div><span>source</span><span> </span><span>/opt/ros/humble/setup.bash</span></div></div><div><div><div>3</div></div><div><span>source</span><span> </span><span>/workspace/aimdk/install/local_setup.bash</span></div></div><div><div><div>4</div></div><div><span>colcon</span><span> </span><span>build</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>编译产物：<code>install/x2_rl_deploy_controller/lib/x2_rl_deploy_controller/x2_rl_deploy_controller</code>。</p></section>
<section><h2>7. 安装 CycloneDDS<a href="#7-安装-cyclonedds"><span>#</span></a></h2><p>仿真二进制默认用 CycloneDDS 作为 RMW，镜像里只有 Fast DDS，不装会报：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Error getting RMW implementation identifier / RMW implementation not installed</span></div></div><div><div><div>2</div></div><div><span>(expected identifier of 'rmw_cyclonedds_cpp')</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>容器内安装：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>update</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>--no-install-recommends</span><span> </span><span>ros-humble-rmw-cyclonedds-cpp</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>之后启动一律设 <code>export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp</code>，让仿真、MC、SDK 三方用同一个 RMW，否则通信不通。</p></section>
<section><h2>8. 解决 ProcessInfo 符号缺失<a href="#8-解决-processinfo-符号缺失"><span>#</span></a></h2><p>两套 <code>aimdk_msgs</code> 并存时容易踩坑：<code>/workspace/aimdk/install/aimdk_msgs</code> 里没有 <code>ProcessInfo</code> 消息，<code>/workspace/x2_rl_deploy/install/aimdk_msgs</code> 里有。仿真加载 <code>monitor_plugin</code> 时会因为找不到 <code>ProcessInfo</code> 的类型支持而段错误：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>undefined symbol: ...get_message_type_support_handle&lt;aimdk_msgs::msg::ProcessInfo...&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>解决办法是把带 <code>ProcessInfo</code> 的那套消息库放在 <code>LD_LIBRARY_PATH</code> 最前面：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>LD_LIBRARY_PATH</span><span><span>=</span><span>/</span></span><span>workspace</span><span>/</span><span>x2_rl_deploy</span><span>/</span><span>install</span><span>/</span><span>aimdk_msgs</span><span>/</span><span>lib</span><span>:</span><span>$LD_LIBRARY_PATH</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>9. 启动仿真与运控<a href="#9-启动仿真与运控"><span>#</span></a></h2><p>把上面的环境变量和步骤整合成一键脚本 <code>start_simulation_stack.sh</code>：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div><span>set</span><span> </span><span>-e</span></div></div><div><div><div>3</div></div><div><span>source</span><span> </span><span>/opt/ros/humble/setup.bash</span></div></div><div><div><div>4</div></div><div><span>source</span><span> </span><span>/workspace/x2_rl_deploy/install/local_setup.bash</span></div></div><div><div><div>5</div></div><div><span>source</span><span> </span><span>/workspace/aimdk/install/local_setup.bash</span></div></div><div><div><div>6</div></div><div><span>export</span><span> </span><span>RMW_IMPLEMENTATION</span><span>=</span><span>rmw_cyclonedds_cpp</span></div></div><div><div><div>7</div></div><div><span>export</span><span> </span><span>MUJOCO_GL</span><span>=</span><span>egl</span></div></div><div><div><div>8</div></div><div><span>export</span><span> </span><span>LD_LIBRARY_PATH</span><span><span>=</span><span>/</span></span><span>workspace</span><span>/</span><span>x2_rl_deploy</span><span>/</span><span>install</span><span>/</span><span>aimdk_msgs</span><span>/</span><span>lib</span><span>:/</span><span>workspace</span><span>/</span><span>x2_rl_deploy</span><span>/</span><span>third_party</span><span>/</span><span>onnxruntime-linux-x64-1</span><span>.</span><span>23</span><span>.</span><span>2</span><span>/</span><span>lib</span><span>:/</span><span>workspace</span><span>/</span><span>sim_mujoco</span><span>/</span><span>bin</span><span>:/</span><span>workspace</span><span>/</span><span>sim_mujoco</span><span>/</span><span>lib</span><span>:/</span><span>opt</span><span>/</span><span>ros</span><span>/</span><span>humble</span><span>/</span><span>lib</span><span>:</span><span>$LD_LIBRARY_PATH</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>cd</span><span> </span><span>/workspace/sim_mujoco/bin</span></div></div><div><div><div>11</div></div><div><span>echo</span><span> </span><span>lx2501_3_t2d5</span><span> &gt; </span><span>sim_robot_name_cache.txt</span></div></div><div><div><div>12</div></div><div><span>echo</span><span> </span><span>/workspace/sim_mujoco/configuration</span><span> &gt; </span><span>sim_configuration_directory_cache.txt</span></div></div><div><div><div>13</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>log/crash</span></div></div><div><div><div>14</div></div><div><span>nohup</span><span> </span><span>bash</span><span> </span><span>./start_sim.sh</span><span> &gt; </span><span>/tmp/sim.log</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>15</div></div><div><span>echo</span><span> </span><span>"sim PID=</span><span>$!</span><span>"</span></div></div><div><div><div>16</div></div><div><span>sleep</span><span> </span><span>8</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>cd</span><span> </span><span>/workspace/x2_rl_deploy</span></div></div><div><div><div>19</div></div><div><span>nohup</span><span> </span><span>./install/x2_rl_deploy_controller/lib/x2_rl_deploy_controller/x2_rl_deploy_controller</span><span> &gt; </span><span>/tmp/mc.log</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>20</div></div><div><span>echo</span><span> </span><span>"mc PID=</span><span>$!</span><span>"</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>启动：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>exec</span><span> </span><span>-d</span><span> </span><span>x2-sim</span><span> </span><span>bash</span><span> </span><span>/workspace/x2_rl_deploy/start_simulation_stack.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>日志分别在容器的 <code>/tmp/sim.log</code> 和 <code>/tmp/mc.log</code>。</p></section>
<section><h2>10. 验证通信<a href="#10-验证通信"><span>#</span></a></h2><p>查看话题（只 source <code>x2_rl_deploy</code> 的 install，避开两套消息的 Python 类型冲突，见第 8 节）：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>exec</span><span> </span><span>-it</span><span> </span><span>x2-sim</span><span> </span><span>bash</span></div></div><div><div><div>2</div></div><div><span>source</span><span> </span><span>/opt/ros/humble/setup.bash</span></div></div><div><div><div>3</div></div><div><span>source</span><span> </span><span>/workspace/x2_rl_deploy/install/local_setup.bash</span></div></div><div><div><div>4</div></div><div><span>export</span><span> </span><span>RMW_IMPLEMENTATION</span><span>=</span><span>rmw_cyclonedds_cpp</span></div></div><div><div><div>5</div></div><div><span>export</span><span> </span><span>LD_LIBRARY_PATH</span><span><span>=</span><span>/</span></span><span>workspace</span><span>/</span><span>x2_rl_deploy</span><span>/</span><span>install</span><span>/</span><span>aimdk_msgs</span><span>/</span><span>lib</span><span>:</span><span>$LD_LIBRARY_PATH</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>ros2</span><span> </span><span>topic</span><span> </span><span>list</span></div></div><div><div><div>8</div></div><div><span>ros2</span><span> </span><span>topic</span><span> </span><span>echo</span><span> </span><span>/aima/hal/joint/arm/state</span><span> </span><span>--once</span></div></div><div><div><div>9</div></div><div><span>ros2</span><span> </span><span>topic</span><span> </span><span>info</span><span> </span><span>/aima/hal/joint/leg/command</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>正常时应看到 <code>Publisher count: 1, Subscription count: 1</code>（MC 发布、仿真订阅），并且 <code>echo</code> 能打印出实时关节数据，说明仿真与运控通信链路已打通。</p><hr /></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2>

<table><thead><tr><th>问题</th><th>解决办法</th></tr></thead><tbody><tr><td>基础镜像拉取失败</td><td>重试 <code>docker pull</code>，或先配镜像加速再拉</td></tr><tr><td>MuJoCo 窗口不显示</td><td>宿主机执行 <code>xhost +si:localuser:root</code>，确认在图形桌面会话</td></tr><tr><td>报 <code>rmw_cyclonedds_cpp</code> 未安装</td><td>第 7 节安装 CycloneDDS，三方统一用同一个 RMW</td></tr><tr><td>段错误 + <code>ProcessInfo</code> 符号缺失</td><td>第 8 节，把带 <code>ProcessInfo</code> 的消息库放 <code>LD_LIBRARY_PATH</code> 最前</td></tr><tr><td><code>start_sim.sh</code> 提示已有实例在跑</td><td>真没有实例时，是脚本 <code>pgrep</code> 把调用它的命令行自己匹配上了；用独立脚本文件启动，别写在 <code>bash -c "..."</code> 单行里</td></tr><tr><td>内存不足导致仿真被杀</td><td>见下一篇「内存占用优化」，减渲染分辨率、关多余插件</td></tr></tbody></table><hr /><section><h3>本网站提供的所有教程仅供学习使用，无任何商务用途!<a href="#本网站提供的所有教程仅供学习使用无任何商务用途"><span>#</span></a></h3></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.levek.top/posts/vm/windows%E5%AE%89%E8%A3%85vmware%E8%99%9A%E6%8B%9F%E6%9C%BA/</id>
      <title type="text">VMware 17.6 安装教程（Windows）</title>
      <published>2026-10-16T00:00:00.000Z</published>
      <updated>2026-10-16T00:00:00.000Z</updated>
      <author><name>levek</name></author>
      <link rel="alternate" href="https://blog.levek.top/posts/vm/windows%E5%AE%89%E8%A3%85vmware%E8%99%9A%E6%8B%9F%E6%9C%BA/"/>
      <summary type="text">VMware Workstation Pro 17.6 图文安装教程：下载、解压、安装到激活全程截图演示，Win 7/8/10/11 通用，零基础也能轻松装好虚拟机～</summary>
      <content type="html"><![CDATA[<section><h2>📥 软件下载<a href="#-软件下载"><span>#</span></a></h2>

<table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>软件名称</td><td>VMware 17.6</td></tr><tr><td>软件大小</td><td>226.86 MB</td></tr><tr><td>安装环境</td><td>Win 11 / Win 10</td></tr></tbody></table><ul>
<li><strong>[123云盘下载链接]</strong>：<a href="https://www.123865.com/s/oJ51Td-lqZlA" target="_blank">https://www.123865.com/s/oJ51Td-lqZlA</a></li>
<li><strong>[百度网盘下载链接]</strong>：<a href="https://pan.baidu.com/s/1nXSfJa2RJFbrHB2OKkL8Hg?pwd=hxrj" target="_blank">https://pan.baidu.com/s/1nXSfJa2RJFbrHB2OKkL8Hg?pwd=hxrj</a>（提取码：<code>hxrj</code>）</li>
</ul><hr /></section>
<section><h2>📖 软件介绍<a href="#-软件介绍"><span>#</span></a></h2><p>VMware（虚拟机）是指通过软件模拟的、具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。通过它，可以在一台电脑上同时运行更多的 Microsoft Windows、Linux、Mac OS X、DOS 等系统，非常适合测试软件、搭建实验环境、体验其他操作系统。</p><hr /></section>
<section><h2>🛠️ 安装步骤<a href="#️-安装步骤"><span>#</span></a></h2><p>下载完成后，鼠标右键解压缩安装包。</p><p></p><figure><img alt="第1步：右键解压缩" loading="lazy" width="450" height="230" src="/_astro/01-%E8%A7%A3%E5%8E%8B%E7%BC%A9.dv3RiGDT_wtGSw.webp" /><figcaption>第1步：右键解压缩</figcaption></figure><p></p><p>**选中 <code>VMware 17.6</code> 安装程序，鼠标右击选择「<strong>以管理员身份运行</strong>」。</p><p></p><figure><img alt="第2步：以管理员身份运行" loading="lazy" width="480" height="243" src="/_astro/02-%E4%BB%A5%E7%AE%A1%E7%90%86%E5%91%98%E8%BA%AB%E4%BB%BD%E8%BF%90%E8%A1%8C.Ctz9P-Ku_Z1cWTOx.webp" /><figcaption>第2步：以管理员身份运行</figcaption></figure><p></p><p><strong>取消勾选</strong>「启动时检查产品更新」和「加入 VMware 客户体验提升计划」，点击「<strong>下一步</strong>」。</p><p></p><figure><img alt="第6步：取消勾选更新与体验计划" loading="lazy" width="1664" height="1312" src="/_astro/06-%E5%8F%96%E6%B6%88%E5%8B%BE%E9%80%89%E6%9B%B4%E6%96%B0%E4%B8%8E%E4%BD%93%E9%AA%8C%E8%AE%A1%E5%88%92.RuZYTxlx_ZA0ndY.webp" /><figcaption>第6步：取消勾选更新与体验计划</figcaption></figure><p></p><p>输入许可证密钥：<code>MC60H-DWHD5-H80U9-6V85M-8280D</code>，点击「<strong>输入</strong>」。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>MC60H-DWHD5-H80U9-6V85M-8280D</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img alt="第11步：输入许可证密钥" loading="lazy" width="495" height="392" src="/_astro/11-%E8%BE%93%E5%85%A5%E8%AE%B8%E5%8F%AF%E8%AF%81%E5%AF%86%E9%92%A5.DBdOd9ZH_1PHWdV.webp" /><figcaption>第11步：输入许可证密钥</figcaption></figure><p></p><blockquote><p>💡 如果不想输入密钥，也可以直接点击「完成」，选择个人非商业用途免费使用。</p></blockquote></section>
<section><h2>✅ 安装完成！<a href="#-安装完成"><span>#</span></a></h2><section><h3>本网站提供的所有教程仅供学习使用，无任何商务用途!<a href="#本网站提供的所有教程仅供学习使用无任何商务用途"><span>#</span></a></h3></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.levek.top/posts/linix/%E7%81%B5%E7%8A%80x2%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/</id>
      <title type="text">灵犀 X2 二次开发指南</title>
      <published>2026-09-21T00:00:00.000Z</published>
      <updated>2026-09-21T00:00:00.000Z</updated>
      <author><name>levek</name></author>
      <link rel="alternate" href="https://blog.levek.top/posts/linix/%E7%81%B5%E7%8A%80x2%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/"/>
      <summary type="text">灵犀 X2 人形机器人二次开发全流程：WSL2 + ROS 2 Humble 环境搭建、代码同步、依赖安装、编译、镜像网络配置、MuJoCo 仿真与故障排查。</summary>
      <content type="html"><![CDATA[<section><h2>1. 环境总览<a href="#1-环境总览"><span>#</span></a></h2><p><strong>表1 环境总览</strong></p>

<table><thead><tr><th>环境</th><th>系统</th><th>路径</th><th>用途</th></tr></thead><tbody><tr><td>机器人</td><td>Ubuntu ARM64，ROS 2 Humble</td><td>~/aimdk（容器内）</td><td>真机编译、控制、SLAM</td></tr><tr><td>Windows</td><td>Windows 11</td><td>—</td><td>网络配置</td></tr></tbody></table><p>SDK 版本：v1.1.0</p><p>参考：
<a href="https://x2-aimdk.agibot.com/zh-cn/latest/" target="_blank">智元机器人灵犀X2</a>
<a href="https://docs.ros.org/en/humble/index.html" target="_blank">ROS2官方文档</a></p><section><h3>2.1 Windows 端静态 IP<a href="#21-windows-端静态-ip"><span>#</span></a></h3><p>打开 ncpa.cpl，找到连接机器人的“以太网”网卡 → 属性 → IPv4：</p><ul>
<li>IP 地址：192.168.88.88</li>
<li>子网掩码：255.255.255.0</li>
<li>网关/DNS：留空</li>
</ul></section><section><h3>2.2 机器人连接<a href="#22-机器人连接"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ping</span><span> </span><span>10.0.1.41</span></div></div><div><div><div>2</div></div><div><span>ssh</span><span> </span><span>agi@10.0.1.41</span><span>   </span><span># 密码通常为 1</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>3. 机器人端开发（SSH + 宿主机编译）<a href="#3-机器人端开发ssh--宿主机编译"><span>#</span></a></h2><p>注意：容器方案在机器人上因内核限制不可用（cannot clone: Operation not permitted），以下均为宿主机直接编译。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ssh</span><span> </span><span>agi@10.0.1.41</span><span>   </span><span># 密码通常为 1</span></div></div><div><div><div>2</div></div><div><span># 进入 SDK 目录</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>~/aimdk</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>4. 常用机器人指令<a href="#4-常用机器人指令"><span>#</span></a></h2><p><code>py_examples</code> 里可直接运行的示例脚本如下（部分功能可能未配备，请谨慎运行）：</p><p></p><figure><img alt="py_examples 目录下的示例脚本" loading="lazy" width="1254" height="254" src="/_astro/01-py-examples-list.C4HSW_Ch_ZbCAmX.webp" /><figcaption>py_examples 目录下的示例脚本</figcaption></figure><p></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>get_mc_action</span><span>          </span><span># 获取运动模式</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>preset_motion_client</span><span>   </span><span># 预设动作</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>mc_locomotion_velocity</span><span> </span><span># 速度控制</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>play_linkcraft</span><span>         </span><span># 播放灵犀工坊作品</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h3>4.1 获取运动模式 get_mc_action<a href="#41-获取运动模式-get_mc_action"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>get_mc_action</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img alt="get_mc_action 的输出" loading="lazy" width="1210" height="195" src="/_astro/03-get-mc-action.BQFvJ_1M_IpT7W.webp" /><figcaption>get_mc_action 的输出</figcaption></figure><p></p><p>输出中的 <code>Mode name</code> 就是当前运动状态，可在最后的运动模式对照表里查对应名称。</p></section><section><h3>4.2 切换运动模式 set_mc_action<a href="#42-切换运动模式-set_mc_action"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>set_mc_action</span><span> </span><span>SD</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>可用的模式缩写：</p><p></p><figure><img alt="set_mc_action 可用缩写" loading="lazy" width="835" height="159" src="/_astro/04-set-mc-action-usage.CWxnxtXd_1gEkGx.webp" /><figcaption>set_mc_action 可用缩写</figcaption></figure><p></p><p>出现下面的输出即视为切换成功：</p><p></p><figure><img alt="set_mc_action 切换成功" loading="lazy" width="1285" height="131" src="/_astro/05-set-mc-action-result.C1mB4Cyt_Z1yBpOt.webp" /><figcaption>set_mc_action 切换成功</figcaption></figure><p></p></section><section><h3>4.3 预设动作 preset_motion_client<a href="#43-预设动作-preset_motion_client"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>preset_motion_client</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>动作—代码对照表：</p>

<table><thead><tr><th>动作名称</th><th>motion</th><th>area</th><th>说明</th><th>动作名称</th><th>motion</th><th>area</th><th>说明</th></tr></thead><tbody><tr><td>右手挥手</td><td>1002</td><td>2</td><td>稳定站立模式下执行</td><td>拥抱</td><td>3008</td><td>11</td><td>同上</td></tr><tr><td>左手挥手</td><td>1002</td><td>1</td><td>同上</td><td>加油</td><td>3011</td><td>11</td><td>同上</td></tr><tr><td>右手握手</td><td>1003</td><td>2</td><td>同上</td><td>双手平举</td><td>1010</td><td>3</td><td>同上</td></tr><tr><td>左手握手</td><td>1003</td><td>1</td><td>同上</td><td>右手平举</td><td>1010</td><td>2</td><td>同上</td></tr><tr><td>右手举手</td><td>1001</td><td>2</td><td>同上</td><td>左手平举</td><td>1010</td><td>1</td><td>同上</td></tr><tr><td>左手举手</td><td>1001</td><td>1</td><td>同上</td><td>拜拜</td><td>3031</td><td>11</td><td>同上</td></tr><tr><td>右手飞吻</td><td>1004</td><td>2</td><td>同上</td><td>动感光波</td><td>3007</td><td>11</td><td>同上</td></tr><tr><td>左手飞吻</td><td>1004</td><td>1</td><td>同上</td><td>右手击掌</td><td>1008</td><td>2</td><td>同上</td></tr><tr><td>鼓掌</td><td>3017</td><td>11</td><td>同上</td><td>左手击掌</td><td>1008</td><td>1</td><td>同上</td></tr><tr><td>右手敬礼</td><td>1013</td><td>2</td><td>同上</td><td>双手打叉</td><td>3009</td><td>11</td><td>同上</td></tr><tr><td>左手敬礼</td><td>1013</td><td>1</td><td>同上</td><td>胸前右手挥手</td><td>1011</td><td>2</td><td>同上</td></tr><tr><td>双手比心</td><td>1007</td><td>3</td><td>同上</td><td>胸前左手挥手</td><td>1011</td><td>1</td><td>同上</td></tr><tr><td>右手比心</td><td>1007</td><td>2</td><td>同上</td><td>鞠躬</td><td>3001</td><td>11</td><td>同上</td></tr><tr><td>双手比心</td><td>1007</td><td>3</td><td>同上</td><td>挠头</td><td>3024</td><td>11</td><td>同上</td></tr><tr><td>右手比心</td><td>1007</td><td>2</td><td>同上</td><td>抓屁股</td><td>3025</td><td>11</td><td>同上</td></tr><tr><td>左手比心</td><td>1007</td><td>1</td><td>同上</td><td></td><td></td><td></td><td></td></tr></tbody></table><p>按提示输入 arm area ID 与 preset motion ID，出现下面输出即为下发成功：</p><p></p><figure><img alt="preset_motion_client 下发成功" loading="lazy" width="1405" height="170" src="/_astro/08-preset-motion-client.BaBYq_xU_Z3ANGf.webp" /><figcaption>preset_motion_client 下发成功</figcaption></figure><p></p></section><section><h3>4.4 速度控制 mc_locomotion_velocity<a href="#44-速度控制-mc_locomotion_velocity"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>mc_locomotion_velocity</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>三个数值按需求填写（0.0—1.0，单位 m/s），数值不要太大，防止机器人误伤：</p><p></p><figure><img alt="mc_locomotion_velocity 的输出" loading="lazy" width="1450" height="300" src="/_astro/09-mc-locomotion-velocity.CIhNDnKl_Z2lyRkS.webp" /><figcaption>mc_locomotion_velocity 的输出</figcaption></figure><p></p></section><section><h3>4.5 播放灵犀工坊作品 play_linkcraft<a href="#45-播放灵犀工坊作品-play_linkcraft"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ros2</span><span> </span><span>run</span><span> </span><span>py_examples</span><span> </span><span>play_linkcraft</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>先列出机器人上已有的作品资源：</p><p></p><figure><img alt="play_linkcraft 资源列表" loading="lazy" width="1479" height="760" src="/_astro/10-play-linkcraft-list.IpsZxL7d_1RDXio.webp" /><figcaption>play_linkcraft 资源列表</figcaption></figure><p></p><p>在提示符处按索引选择作品，出现 <code>Play success</code> 即为播放成功：</p><p></p><figure><img alt="play_linkcraft 播放成功" loading="lazy" width="1354" height="315" src="/_astro/11-play-linkcraft-result.DqG6lBcS_Zn17uc.webp" /><figcaption>play_linkcraft 播放成功</figcaption></figure><p></p></section><section><h3>4.6 运动模式对照<a href="#46-运动模式对照"><span>#</span></a></h3><p><strong>表2 运动模式对照</strong></p>

<table><thead><tr><th>缩写</th><th>模式名</th><th>说明</th></tr></thead><tbody><tr><td>PD</td><td>PASSIVE_DEFAULT</td><td>零力矩</td></tr><tr><td>DD</td><td>DAMPING_DEFAULT</td><td>阻尼模式</td></tr><tr><td>JD</td><td>JOINT_DEFAULT</td><td>位置控制站立（关节锁定）</td></tr><tr><td>SD</td><td>STAND_DEFAULT</td><td>稳定站立（自动平衡）</td></tr><tr><td>LD</td><td>LOCOMOTION_DEFAULT</td><td>行走/奔跑</td></tr></tbody></table><p>官方文档里的完整版本（含使用场景）：</p><p></p><figure><img alt="运动模式表" loading="lazy" width="1014" height="415" src="/_astro/02-motion-mode-table.BFgm1wT9_Z1yqgxg.webp" /><figcaption>运动模式表</figcaption></figure><p></p></section></section>
<section><h2>5. 已知问题与故障排查<a href="#5-已知问题与故障排查"><span>#</span></a></h2><section><h3>5.1 编译相关<a href="#51-编译相关"><span>#</span></a></h3><p><strong>表4 编译问题排查</strong></p>

<table><thead><tr><th>报错</th><th>原因</th><th>解决</th></tr></thead><tbody><tr><td>Duplicate package names</td><td>src 下存在同名包</td><td>删除多余副本（备份目录移出 src）</td></tr><tr><td>cannot find …/urdf</td><td>x2_description 缺少 urdf 目录</td><td>在 X2_URDF-v1.3.0/ 下 mkdir urdf &amp;&amp; cp *.urdf urdf/</td></tr><tr><td>Undefined symbol: ProcessInfo</td><td>aimdk_msgs 版本缺消息</td><td>用 x2_rl_deploy/aimdk_msgs 替换并补全</td></tr><tr><td>ImportError: McLocomotionVelocity</td><td>替换后缺原 SDK 消息</td><td>从备份恢复 aimdk_msgs，合入 6 个 HDS 消息</td></tr></tbody></table></section><section><h3>5.2 仿真相关<a href="#52-仿真相关"><span>#</span></a></h3><p>现象：进入 RL_ACTIVE 后机器人持续抽搐或直接躺倒，无法站立。</p><p>已尝试：</p><ul>
<li>补全 DEFAULT_JOINT_POS 为 31 个关节</li>
<li>重置时显式设置 pelvis 完整位姿（位置+四元数）</li>
<li>调整 pelvis 高度（0.40 / 0.50 / 0.55）</li>
<li>调整稳定步数（500 / 3000）</li>
<li>切换 PD 增益（standup_gains / rl_gains）</li>
<li>放宽 GRAVITY_PITCH_LIMIT</li>
</ul><p>结论：策略在 IsaacLab 训练，与 MuJoCo 物理环境存在差异，需官方提供 sim2sim 对齐配置。</p></section></section>
<section><h2>6. 安全注意事项<a href="#6-安全注意事项"><span>#</span></a></h2><ul>
<li>停止 mc 模块前必须确保机器人有吊挂或安全支撑。</li>
<li>真机控制夹爪/灯带前，先确认当前运动模式，避免冲突。</li>
<li>sudo 权限受限，不要随意安装系统包。</li>
<li>容器方案在机器人上不可用，请使用宿主机直接编译。</li>
</ul></section>
<section><h2>7. 版本与备份<a href="#7-版本与备份"><span>#</span></a></h2><ul>
<li>机器人 SDK：v1.1.0</li>
<li>WSL 工作空间：~/aimdk_sim_ws</li>
<li>备份目录：~/aimdk_msgs_bak（已移出 src）</li>
</ul><section><h3>本网站提供的所有教程仅供学习使用，无任何商务用途!<a href="#本网站提供的所有教程仅供学习使用无任何商务用途"><span>#</span></a></h3></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.levek.top/posts/actounting/first_article/</id>
      <title type="text">记账软件</title>
      <published>2025-12-24T00:00:00.000Z</published>
      <updated>2025-12-24T00:00:00.000Z</updated>
      <author><name>levek</name></author>
      <link rel="alternate" href="https://blog.levek.top/posts/actounting/first_article/"/>
      <summary type="text">一款简洁、无广告的记账软件</summary>
      <content type="html"><![CDATA[<section><h2>🌟 项目概述<a href="#-项目概述"><span>#</span></a></h2><hr /><p>记账软件支持记录支出收入、背景替换等功能
同时：支持商业记录商单</p><ul>
<li>成本</li>
<li>售价</li>
<li>其他成本</li>
<li>利润</li>
</ul><hr /></section>
<section><h2>🌟 Bilibili视频介绍<a href="#-bilibili视频介绍"><span>#</span></a></h2><hr /><p>敬请期待！</p><hr /></section>
<section><h2>🌟 下载方式<a href="#-下载方式"><span>#</span></a></h2><hr /><ul>
<li><strong>直接下载</strong>: <a href="https://ghfast.top/github.com/levek-lcd/accounting/releases/download/Android/Acounting-V1.0.0.apk" target="_blank">记账软件V1.0.0</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.levek.top/posts/figer_tp/figeger_transport/</id>
      <title type="text">图片转换工具</title>
      <published>2025-11-10T00:00:00.000Z</published>
      <updated>2025-11-11T00:00:00.000Z</updated>
      <author><name>levek</name></author>
      <link rel="alternate" href="https://blog.levek.top/posts/figer_tp/figeger_transport/"/>
      <summary type="text">JPG图片转换工具，JPG-to-PNG JPG-to-ICO PNG-to-JPG,改变照片尺寸等</summary>
      <content type="html"><![CDATA[<section><h1>Python第三方库安装<a href="#python第三方库安装"><span>#</span></a></h1><ul>
<li>PIL</li>
<li>tkinter</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#打开命令提示符输入：</span></div></div><div><div><div>2</div></div><div><span><span>pip install </span><span>PIL</span><span> tkinter</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h1>程序代码<a href="#程序代码"><span>#</span></a></h1><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> os</span></div></div><div><div><div>2</div></div><div><span>from</span><span><span> </span><span>PIL</span><span> </span></span><span>import</span><span> Image</span></div></div><div><div><div>3</div></div><div><span>import</span><span> tkinter </span><span>as</span><span> tk</span></div></div><div><div><div>4</div></div><div><span>from</span><span> tkinter </span><span>import</span><span> filedialog, messagebox, ttk</span></div></div><div><div><div>5</div></div><div><span>import</span><span> math</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 证件照标准尺寸（单位：毫米）</span></div></div><div><div><div>8</div></div><div><span><span>PHOTO_SIZES</span><span> </span><span>=</span><span> {</span></span></div></div><div><div><div>9</div></div><div><span>    </span><span>"一寸"</span><span>: (</span><span>25</span><span>, </span><span>35</span><span>),</span></div></div><div><div><div>10</div></div><div><span>    </span><span>"小一寸"</span><span>: (</span><span>22</span><span>, </span><span>32</span><span>),</span></div></div><div><div><div>11</div></div><div><span>    </span><span>"大一寸"</span><span>: (</span><span>33</span><span>, </span><span>48</span><span>),</span></div></div><div><div><div>12</div></div><div><span>    </span><span>"两寸"</span><span>: (</span><span>35</span><span>, </span><span>49</span><span>),</span></div></div><div><div><div>13</div></div><div><span>    </span><span>"小二寸"</span><span>: (</span><span>35</span><span>, </span><span>45</span><span>),</span></div></div><div><div><div>14</div></div><div><span>    </span><span>"大二寸"</span><span>: (</span><span>35</span><span>, </span><span>53</span><span>),</span></div></div><div><div><div>15</div></div><div><span>    </span><span>"五寸"</span><span>: (</span><span>89</span><span>, </span><span>127</span><span>),</span></div></div><div><div><div>16</div></div><div><span>    </span><span>"六寸"</span><span>: (</span><span>102</span><span>, </span><span>152</span><span>),</span></div></div><div><div><div>17</div></div><div><span>    </span><span>"七寸"</span><span>: (</span><span>127</span><span>, </span><span>178</span><span>),</span></div></div><div><div><div>18</div></div><div><span>    </span><span>"八寸"</span><span>: (</span><span>152</span><span>, </span><span>203</span><span>),</span></div></div><div><div><div>19</div></div><div><span>    </span><span>"十寸"</span><span>: (</span><span>203</span><span>, </span><span>254</span><span>),</span></div></div><div><div><div>20</div></div><div><span>    </span><span>"十二寸"</span><span>: (</span><span>305</span><span>, </span><span>254</span><span>),</span></div></div><div><div><div>21</div></div><div><span>    </span><span>"自定义"</span><span>: (</span><span>0</span><span>, </span><span>0</span><span>)  </span><span># 自定义尺寸</span></div></div><div><div><div>22</div></div><div><span>}</span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span># DPI设置（每英寸点数）</span></div></div><div><div><div>25</div></div><div><span><span>DPI</span><span> </span><span>=</span><span> </span></span><span>300</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span>def</span><span> </span><span>mm_to_pixels</span><span>(</span><span>mm</span><span>,</span><span><span> </span><span>dpi</span></span><span><span>=</span><span>DPI</span><span>):</span></span></div></div><div><div><div>28</div></div><div><span>    </span><span>"""将毫米转换为像素"""</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>inches </span><span>=</span><span> mm </span><span>/</span><span> </span><span>25.4</span></div></div><div><div><div>30</div></div><div><span>    </span><span>return</span><span> </span><span>int</span><span><span>(inches </span><span>*</span><span> dpi)</span></span></div></div><div><div><div>31</div></div><div>
</div></div><div><div><div>32</div></div><div><span>def</span><span> </span><span>convert_image</span><span>(</span><span>input_path</span><span>,</span><span><span> </span><span>output_path</span></span><span>,</span><span><span> </span><span>conversion_type</span></span><span>,</span><span><span> </span><span>sizes</span></span><span>=</span><span>None</span><span>):</span></div></div><div><div><div>33</div></div><div><span>    </span><span>"""</span></div></div><div><div><div>34</div></div><div><span><span>    </span></span><span>图像格式转换函数</span></div></div><div><div><div>35</div></div><div>
</div></div><div><div><div>36</div></div><div><span><span>    </span></span><span>参数:</span></div></div><div><div><div>37</div></div><div><span><span>    </span></span><span>input_path: 输入文件路径</span></div></div><div><div><div>38</div></div><div><span><span>    </span></span><span>output_path: 输出文件路径</span></div></div><div><div><div>39</div></div><div><span><span>    </span></span><span>conversion_type: 转换类型 ('jpg_to_ico', 'jpg_to_png', 'png_to_jpg')</span></div></div><div><div><div>40</div></div><div><span><span>    </span></span><span>sizes: ICO 文件包含的尺寸列表，仅对 jpg_to_ico 转换有效</span></div></div><div><div><div>41</div></div><div><span><span>    </span></span><span>"""</span></div></div><div><div><div>42</div></div><div><span>    </span><span>try</span><span>:</span></div></div><div><div><div>43</div></div><div><span>        </span><span>if</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_ico'</span><span>:</span></div></div><div><div><div>44</div></div><div><span>            </span><span>if</span><span> sizes </span><span>is</span><span> </span><span>None</span><span>:</span></div></div><div><div><div>45</div></div><div><span><span>                </span></span><span>sizes </span><span>=</span><span> [</span><span>16</span><span>, </span><span>32</span><span>, </span><span>48</span><span>, </span><span>64</span><span>]</span></div></div><div><div><div>46</div></div><div>
</div></div><div><div><div>47</div></div><div><span>            </span><span># 打开原始图像</span></div></div><div><div><div>48</div></div><div><span>            </span><span>with</span><span><span> Image.</span><span>open</span><span>(input_path) </span></span><span>as</span><span> img:</span></div></div><div><div><div>49</div></div><div><span>                </span><span># 转换为 RGBA 模式（ICO 格式支持透明度）</span></div></div><div><div><div>50</div></div><div><span>                </span><span>if</span><span><span> img.mode </span><span>!=</span><span> </span></span><span>'RGBA'</span><span>:</span></div></div><div><div><div>51</div></div><div><span><span>                    </span></span><span>img </span><span>=</span><span> img.</span><span>convert</span><span>(</span><span>'RGBA'</span><span>)</span></div></div><div><div><div>52</div></div><div>
</div></div><div><div><div>53</div></div><div><span>                </span><span># 创建不同尺寸的图像列表</span></div></div><div><div><div>54</div></div><div><span><span>                </span></span><span>icon_sizes </span><span>=</span><span> [(size, size) </span><span>for</span><span> size </span><span>in</span><span> sizes]</span></div></div><div><div><div>55</div></div><div><span><span>                </span></span><span>images </span><span>=</span><span> []</span></div></div><div><div><div>56</div></div><div>
</div></div><div><div><div>57</div></div><div><span>                </span><span>for</span><span> size </span><span>in</span><span> icon_sizes:</span></div></div><div><div><div>58</div></div><div><span>                    </span><span># 调整图像大小并使用高质量的缩略图算法</span></div></div><div><div><div>59</div></div><div><span><span>                    </span></span><span>resized_img </span><span>=</span><span> img.</span><span>resize</span><span>(size, Image.Resampling.</span><span>LANCZOS</span><span>)</span></div></div><div><div><div>60</div></div><div><span><span>                    </span></span><span>images.</span><span>append</span><span>(resized_img)</span></div></div><div><div><div>61</div></div><div>
</div></div><div><div><div>62</div></div><div><span>                </span><span># 保存为 ICO 格式</span></div></div><div><div><div>63</div></div><div><span><span>                </span></span><span>images[</span><span>0</span><span><span>].</span><span>save</span><span>(</span></span></div></div><div><div><div>64</div></div><div><span><span>                    </span></span><span>output_path,</span></div></div><div><div><div>65</div></div><div><span>                    </span><span>format</span><span>=</span><span>'ICO'</span><span>,</span></div></div><div><div><div>66</div></div><div><span>                    </span><span>append_images</span><span><span>=</span><span>images[</span></span><span>1</span><span>:],</span></div></div><div><div><div>67</div></div><div><span>                    </span><span>optimize</span><span>=</span><span>True</span></div></div><div><div><div>68</div></div><div><span><span>                </span></span><span>)</span></div></div><div><div><div>69</div></div><div>
</div></div><div><div><div>70</div></div><div><span>        </span><span>elif</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_png'</span><span>:</span></div></div><div><div><div>71</div></div><div><span>            </span><span>with</span><span><span> Image.</span><span>open</span><span>(input_path) </span></span><span>as</span><span> img:</span></div></div><div><div><div>72</div></div><div><span>                </span><span># 转换为 RGB 模式（PNG 格式支持透明度，但JPG没有透明度）</span></div></div><div><div><div>73</div></div><div><span>                </span><span>if</span><span><span> img.mode </span><span>!=</span><span> </span></span><span>'RGB'</span><span>:</span></div></div><div><div><div>74</div></div><div><span><span>                    </span></span><span>img </span><span>=</span><span> img.</span><span>convert</span><span>(</span><span>'RGB'</span><span>)</span></div></div><div><div><div>75</div></div><div><span><span>                </span></span><span>img.</span><span>save</span><span>(output_path, </span><span>format</span><span>=</span><span>'PNG'</span><span>, </span><span>optimize</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>76</div></div><div>
</div></div><div><div><div>77</div></div><div><span>        </span><span>elif</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'png_to_jpg'</span><span>:</span></div></div><div><div><div>78</div></div><div><span>            </span><span>with</span><span><span> Image.</span><span>open</span><span>(input_path) </span></span><span>as</span><span> img:</span></div></div><div><div><div>79</div></div><div><span>                </span><span># 转换为 RGB 模式（JPG 不支持透明度）</span></div></div><div><div><div>80</div></div><div><span>                </span><span>if</span><span><span> img.mode </span><span>!=</span><span> </span></span><span>'RGB'</span><span>:</span></div></div><div><div><div>81</div></div><div><span>                    </span><span># 创建一个白色背景，将透明区域填充为白色</span></div></div><div><div><div>82</div></div><div><span><span>                    </span></span><span>background </span><span>=</span><span> Image.</span><span>new</span><span>(</span><span>'RGB'</span><span>, img.size, (</span><span>255</span><span>, </span><span>255</span><span>, </span><span>255</span><span>))</span></div></div><div><div><div>83</div></div><div><span>                    </span><span>if</span><span><span> img.mode </span><span>==</span><span> </span></span><span>'RGBA'</span><span>:</span></div></div><div><div><div>84</div></div><div><span>                        </span><span># 使用alpha通道作为掩码</span></div></div><div><div><div>85</div></div><div><span><span>                        </span></span><span>background.</span><span>paste</span><span>(img, </span><span>mask</span><span><span>=</span><span>img.</span><span>split</span><span>()[</span><span>-</span></span><span>1</span><span>])</span></div></div><div><div><div>86</div></div><div><span>                    </span><span>else</span><span>:</span></div></div><div><div><div>87</div></div><div><span><span>                        </span></span><span>background.</span><span>paste</span><span>(img)</span></div></div><div><div><div>88</div></div><div><span><span>                    </span></span><span>img </span><span>=</span><span> background</span></div></div><div><div><div>89</div></div><div>
</div></div><div><div><div>90</div></div><div><span>                </span><span># 设置JPG质量（0-100），默认75</span></div></div><div><div><div>91</div></div><div><span><span>                </span></span><span>img.</span><span>save</span><span>(output_path, </span><span>format</span><span>=</span><span>'JPEG'</span><span>, </span><span>quality</span><span>=</span><span>95</span><span>, </span><span>optimize</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>92</div></div><div>
</div></div><div><div><div>93</div></div><div><span>        </span><span>return</span><span> </span><span>True</span><span>, </span><span>f</span><span>"转换成功！文件已保存至: </span><span>{</span><span>output_path</span><span>}</span><span>"</span></div></div><div><div><div>94</div></div><div>
</div></div><div><div><div>95</div></div><div><span>    </span><span>except</span><span> </span><span>Exception</span><span> </span><span>as</span><span> e:</span></div></div><div><div><div>96</div></div><div><span>        </span><span>return</span><span> </span><span>False</span><span>, </span><span>f</span><span>"转换失败: </span><span>{</span><span>str</span><span>(e)</span><span>}</span><span>"</span></div></div><div><div><div>97</div></div><div>
</div></div><div><div><div>98</div></div><div><span>def</span><span> </span><span>crop_photo</span><span>(</span><span>input_path</span><span>,</span><span><span> </span><span>output_path</span></span><span>,</span><span><span> </span><span>photo_size</span></span><span>,</span><span><span> </span><span>dpi</span></span><span><span>=</span><span>DPI</span><span>,</span></span><span><span> </span><span>custom_width</span></span><span>=</span><span>0</span><span>,</span><span><span> </span><span>custom_height</span></span><span>=</span><span>0</span><span>):</span></div></div><div><div><div>99</div></div><div><span>    </span><span>"""</span></div></div><div><div><div>100</div></div><div><span><span>    </span></span><span>裁切证件照函数</span></div></div><div><div><div>101</div></div><div>
</div></div><div><div><div>102</div></div><div><span><span>    </span></span><span>参数:</span></div></div><div><div><div>103</div></div><div><span><span>    </span></span><span>input_path: 输入文件路径</span></div></div><div><div><div>104</div></div><div><span><span>    </span></span><span>output_path: 输出文件路径</span></div></div><div><div><div>105</div></div><div><span><span>    </span></span><span>photo_size: 证件照尺寸名称</span></div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>dpi: 每英寸点数</span></div></div><div><div><div>107</div></div><div><span><span>    </span></span><span>custom_width: 自定义宽度（毫米）</span></div></div><div><div><div>108</div></div><div><span><span>    </span></span><span>custom_height: 自定义高度（毫米）</span></div></div><div><div><div>109</div></div><div><span><span>    </span></span><span>"""</span></div></div><div><div><div>110</div></div><div><span>    </span><span>try</span><span>:</span></div></div><div><div><div>111</div></div><div><span>        </span><span># 获取尺寸（毫米）</span></div></div><div><div><div>112</div></div><div><span>        </span><span>if</span><span><span> photo_size </span><span>==</span><span> </span></span><span>"自定义"</span><span>:</span></div></div><div><div><div>113</div></div><div><span><span>            </span></span><span>width_mm, height_mm </span><span>=</span><span> custom_width, custom_height</span></div></div><div><div><div>114</div></div><div><span>        </span><span>else</span><span>:</span></div></div><div><div><div>115</div></div><div><span><span>            </span></span><span>width_mm, height_mm </span><span>=</span><span> </span><span>PHOTO_SIZES</span><span>[photo_size]</span></div></div><div><div><div>116</div></div><div>
</div></div><div><div><div>117</div></div><div><span>        </span><span># 转换为像素</span></div></div><div><div><div>118</div></div><div><span><span>        </span></span><span>width_px </span><span>=</span><span> </span><span>mm_to_pixels</span><span>(width_mm, dpi)</span></div></div><div><div><div>119</div></div><div><span><span>        </span></span><span>height_px </span><span>=</span><span> </span><span>mm_to_pixels</span><span>(height_mm, dpi)</span></div></div><div><div><div>120</div></div><div>
</div></div><div><div><div>121</div></div><div><span>        </span><span># 打开原始图像</span></div></div><div><div><div>122</div></div><div><span>        </span><span>with</span><span><span> Image.</span><span>open</span><span>(input_path) </span></span><span>as</span><span> img:</span></div></div><div><div><div>123</div></div><div><span>            </span><span># 计算裁切区域</span></div></div><div><div><div>124</div></div><div><span><span>            </span></span><span>img_width, img_height </span><span>=</span><span> img.size</span></div></div><div><div><div>125</div></div><div><span><span>            </span></span><span>target_ratio </span><span>=</span><span> width_px </span><span>/</span><span> height_px</span></div></div><div><div><div>126</div></div><div><span><span>            </span></span><span>img_ratio </span><span>=</span><span> img_width </span><span>/</span><span> img_height</span></div></div><div><div><div>127</div></div><div>
</div></div><div><div><div>128</div></div><div><span>            </span><span>if</span><span><span> img_ratio </span><span>&gt;</span><span> target_ratio:</span></span></div></div><div><div><div>129</div></div><div><span>                </span><span># 图像更宽，裁切左右</span></div></div><div><div><div>130</div></div><div><span><span>                </span></span><span>new_width </span><span>=</span><span> </span><span>int</span><span><span>(img_height </span><span>*</span><span> target_ratio)</span></span></div></div><div><div><div>131</div></div><div><span><span>                </span></span><span>left </span><span>=</span><span> (img_width </span><span>-</span><span> new_width) </span><span>//</span><span> </span><span>2</span></div></div><div><div><div>132</div></div><div><span><span>                </span></span><span>top </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>133</div></div><div><span><span>                </span></span><span>right </span><span>=</span><span> left </span><span>+</span><span> new_width</span></div></div><div><div><div>134</div></div><div><span><span>                </span></span><span>bottom </span><span>=</span><span> img_height</span></div></div><div><div><div>135</div></div><div><span>            </span><span>else</span><span>:</span></div></div><div><div><div>136</div></div><div><span>                </span><span># 图像更高，裁切上下</span></div></div><div><div><div>137</div></div><div><span><span>                </span></span><span>new_height </span><span>=</span><span> </span><span>int</span><span><span>(img_width </span><span>/</span><span> target_ratio)</span></span></div></div><div><div><div>138</div></div><div><span><span>                </span></span><span>left </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>139</div></div><div><span><span>                </span></span><span>top </span><span>=</span><span> (img_height </span><span>-</span><span> new_height) </span><span>//</span><span> </span><span>2</span></div></div><div><div><div>140</div></div><div><span><span>                </span></span><span>right </span><span>=</span><span> img_width</span></div></div><div><div><div>141</div></div><div><span><span>                </span></span><span>bottom </span><span>=</span><span> top </span><span>+</span><span> new_height</span></div></div><div><div><div>142</div></div><div>
</div></div><div><div><div>143</div></div><div><span>            </span><span># 裁切图像</span></div></div><div><div><div>144</div></div><div><span><span>            </span></span><span>cropped_img </span><span>=</span><span> img.</span><span>crop</span><span>((left, top, right, bottom))</span></div></div><div><div><div>145</div></div><div>
</div></div><div><div><div>146</div></div><div><span>            </span><span># 调整到目标尺寸</span></div></div><div><div><div>147</div></div><div><span><span>            </span></span><span>resized_img </span><span>=</span><span> cropped_img.</span><span>resize</span><span>((width_px, height_px), Image.Resampling.</span><span>LANCZOS</span><span>)</span></div></div><div><div><div>148</div></div><div>
</div></div><div><div><div>149</div></div><div><span>            </span><span># 保存图像</span></div></div><div><div><div>150</div></div><div><span>            </span><span>if</span><span><span> output_path.</span><span>lower</span><span>().</span><span>endswith</span><span>(</span></span><span>'.jpg'</span><span>) </span><span>or</span><span><span> output_path.</span><span>lower</span><span>().</span><span>endswith</span><span>(</span></span><span>'.jpeg'</span><span>):</span></div></div><div><div><div>151</div></div><div><span>                </span><span>if</span><span><span> resized_img.mode </span><span>!=</span><span> </span></span><span>'RGB'</span><span>:</span></div></div><div><div><div>152</div></div><div><span><span>                    </span></span><span>resized_img </span><span>=</span><span> resized_img.</span><span>convert</span><span>(</span><span>'RGB'</span><span>)</span></div></div><div><div><div>153</div></div><div><span><span>                </span></span><span>resized_img.</span><span>save</span><span>(output_path, </span><span>format</span><span>=</span><span>'JPEG'</span><span>, </span><span>quality</span><span>=</span><span>95</span><span>, </span><span>optimize</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>154</div></div><div><span>            </span><span>else</span><span>:</span></div></div><div><div><div>155</div></div><div><span><span>                </span></span><span>resized_img.</span><span>save</span><span>(output_path, </span><span>optimize</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>156</div></div><div>
</div></div><div><div><div>157</div></div><div><span>        </span><span>return</span><span> </span><span>True</span><span>, </span><span>f</span><span>"裁切成功！</span><span>{</span><span>photo_size</span><span>}</span><span>照片已保存至: </span><span>{</span><span>output_path</span><span>}</span><span>"</span></div></div><div><div><div>158</div></div><div>
</div></div><div><div><div>159</div></div><div><span>    </span><span>except</span><span> </span><span>Exception</span><span> </span><span>as</span><span> e:</span></div></div><div><div><div>160</div></div><div><span>        </span><span>return</span><span> </span><span>False</span><span>, </span><span>f</span><span>"裁切失败: </span><span>{</span><span>str</span><span>(e)</span><span>}</span><span>"</span></div></div><div><div><div>161</div></div><div>
</div></div><div><div><div>162</div></div><div><span>def</span><span> </span><span>select_input_file</span><span>():</span></div></div><div><div><div>163</div></div><div><span>    </span><span>"""选择输入文件"""</span></div></div><div><div><div>164</div></div><div><span>    </span><span># 根据选择的转换类型设置文件过滤器</span></div></div><div><div><div>165</div></div><div><span>    </span><span>if</span><span><span> tab_control.</span><span>index</span><span>(tab_control.</span><span>select</span><span>()) </span><span>==</span><span> </span></span><span>0</span><span>:  </span><span># 格式转换标签</span></div></div><div><div><div>166</div></div><div><span><span>        </span></span><span>conversion_type </span><span>=</span><span> conversion_var.</span><span>get</span><span>()</span></div></div><div><div><div>167</div></div><div>
</div></div><div><div><div>168</div></div><div><span>        </span><span>if</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_ico'</span><span> </span><span>or</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_png'</span><span>:</span></div></div><div><div><div>169</div></div><div><span><span>            </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"JPG 文件"</span><span>, </span><span>"*.jpg;*.jpeg"</span><span>), (</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>170</div></div><div><span>        </span><span>elif</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'png_to_jpg'</span><span>:</span></div></div><div><div><div>171</div></div><div><span><span>            </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"PNG 文件"</span><span>, </span><span>"*.png"</span><span>), (</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>172</div></div><div><span>        </span><span>else</span><span>:</span></div></div><div><div><div>173</div></div><div><span><span>            </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>174</div></div><div><span>    </span><span>else</span><span>:  </span><span># 证件照裁切标签</span></div></div><div><div><div>175</div></div><div><span><span>        </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"图片文件"</span><span>, </span><span>"*.jpg;*.jpeg;*.png;*.bmp"</span><span>), (</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>176</div></div><div>
</div></div><div><div><div>177</div></div><div><span><span>    </span></span><span>file_path </span><span>=</span><span> filedialog.</span><span>askopenfilename</span><span>(</span></div></div><div><div><div>178</div></div><div><span>        </span><span>title</span><span>=</span><span>"选择输入文件"</span><span>,</span></div></div><div><div><div>179</div></div><div><span>        </span><span>filetypes</span><span><span>=</span><span>filetypes</span></span></div></div><div><div><div>180</div></div><div><span><span>    </span></span><span>)</span></div></div><div><div><div>181</div></div><div>
</div></div><div><div><div>182</div></div><div><span>    </span><span>if</span><span> file_path:</span></div></div><div><div><div>183</div></div><div><span><span>        </span></span><span>entry_input.</span><span>delete</span><span>(</span><span>0</span><span><span>, tk.</span><span>END</span><span>)</span></span></div></div><div><div><div>184</div></div><div><span><span>        </span></span><span>entry_input.</span><span>insert</span><span>(</span><span>0</span><span>, file_path)</span></div></div><div><div><div>185</div></div><div>
</div></div><div><div><div>186</div></div><div><span>        </span><span># 自动生成输出路径</span></div></div><div><div><div>187</div></div><div><span><span>        </span></span><span>base_name </span><span>=</span><span> os.path.</span><span>splitext</span><span>(file_path)[</span><span>0</span><span>]</span></div></div><div><div><div>188</div></div><div>
</div></div><div><div><div>189</div></div><div><span>        </span><span>if</span><span><span> tab_control.</span><span>index</span><span>(tab_control.</span><span>select</span><span>()) </span><span>==</span><span> </span></span><span>0</span><span>:  </span><span># 格式转换标签</span></div></div><div><div><div>190</div></div><div><span><span>            </span></span><span>conversion_type </span><span>=</span><span> conversion_var.</span><span>get</span><span>()</span></div></div><div><div><div>191</div></div><div><span>            </span><span>if</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_ico'</span><span>:</span></div></div><div><div><div>192</div></div><div><span><span>                </span></span><span>output_path </span><span>=</span><span> base_name </span><span>+</span><span> </span><span>".ico"</span></div></div><div><div><div>193</div></div><div><span>            </span><span>elif</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_png'</span><span>:</span></div></div><div><div><div>194</div></div><div><span><span>                </span></span><span>output_path </span><span>=</span><span> base_name </span><span>+</span><span> </span><span>".png"</span></div></div><div><div><div>195</div></div><div><span>            </span><span>elif</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'png_to_jpg'</span><span>:</span></div></div><div><div><div>196</div></div><div><span><span>                </span></span><span>output_path </span><span>=</span><span> base_name </span><span>+</span><span> </span><span>".jpg"</span></div></div><div><div><div>197</div></div><div><span>        </span><span>else</span><span>:  </span><span># 证件照裁切标签</span></div></div><div><div><div>198</div></div><div><span><span>            </span></span><span>output_path </span><span>=</span><span> base_name </span><span>+</span><span> </span><span>"_cropped.jpg"</span></div></div><div><div><div>199</div></div><div>
</div></div><div><div><div>200</div></div><div><span><span>        </span></span><span>entry_output.</span><span>delete</span><span>(</span><span>0</span><span><span>, tk.</span><span>END</span><span>)</span></span></div></div><div><div><div>201</div></div><div><span><span>        </span></span><span>entry_output.</span><span>insert</span><span>(</span><span>0</span><span>, output_path)</span></div></div><div><div><div>202</div></div><div>
</div></div><div><div><div>203</div></div><div><span>        </span><span># 更新尺寸选择框的状态</span></div></div><div><div><div>204</div></div><div><span><span>        </span></span><span>update_size_selection</span><span>()</span></div></div><div><div><div>205</div></div><div>
</div></div><div><div><div>206</div></div><div><span>def</span><span> </span><span>select_output_file</span><span>():</span></div></div><div><div><div>207</div></div><div><span>    </span><span>"""选择输出文件"""</span></div></div><div><div><div>208</div></div><div><span>    </span><span>if</span><span><span> tab_control.</span><span>index</span><span>(tab_control.</span><span>select</span><span>()) </span><span>==</span><span> </span></span><span>0</span><span>:  </span><span># 格式转换标签</span></div></div><div><div><div>209</div></div><div><span><span>        </span></span><span>conversion_type </span><span>=</span><span> conversion_var.</span><span>get</span><span>()</span></div></div><div><div><div>210</div></div><div>
</div></div><div><div><div>211</div></div><div><span>        </span><span>if</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_ico'</span><span>:</span></div></div><div><div><div>212</div></div><div><span><span>            </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"ICO 文件"</span><span>, </span><span>"*.ico"</span><span>), (</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>213</div></div><div><span><span>            </span></span><span>defaultextension </span><span>=</span><span> </span><span>".ico"</span></div></div><div><div><div>214</div></div><div><span>        </span><span>elif</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_png'</span><span>:</span></div></div><div><div><div>215</div></div><div><span><span>            </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"PNG 文件"</span><span>, </span><span>"*.png"</span><span>), (</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>216</div></div><div><span><span>            </span></span><span>defaultextension </span><span>=</span><span> </span><span>".png"</span></div></div><div><div><div>217</div></div><div><span>        </span><span>elif</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'png_to_jpg'</span><span>:</span></div></div><div><div><div>218</div></div><div><span><span>            </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"JPG 文件"</span><span>, </span><span>"*.jpg;*.jpeg"</span><span>), (</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>219</div></div><div><span><span>            </span></span><span>defaultextension </span><span>=</span><span> </span><span>".jpg"</span></div></div><div><div><div>220</div></div><div><span>        </span><span>else</span><span>:</span></div></div><div><div><div>221</div></div><div><span><span>            </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>222</div></div><div><span><span>            </span></span><span>defaultextension </span><span>=</span><span> </span><span>""</span></div></div><div><div><div>223</div></div><div><span>    </span><span>else</span><span>:  </span><span># 证件照裁切标签</span></div></div><div><div><div>224</div></div><div><span><span>        </span></span><span>filetypes </span><span>=</span><span> [(</span><span>"JPG 文件"</span><span>, </span><span>"*.jpg;*.jpeg"</span><span>), (</span><span>"PNG 文件"</span><span>, </span><span>"*.png"</span><span>), (</span><span>"所有文件"</span><span>, </span><span>"*.*"</span><span>)]</span></div></div><div><div><div>225</div></div><div><span><span>        </span></span><span>defaultextension </span><span>=</span><span> </span><span>".jpg"</span></div></div><div><div><div>226</div></div><div>
</div></div><div><div><div>227</div></div><div><span><span>    </span></span><span>file_path </span><span>=</span><span> filedialog.</span><span>asksaveasfilename</span><span>(</span></div></div><div><div><div>228</div></div><div><span>        </span><span>title</span><span>=</span><span>"保存输出文件"</span><span>,</span></div></div><div><div><div>229</div></div><div><span>        </span><span>defaultextension</span><span><span>=</span><span>defaultextension,</span></span></div></div><div><div><div>230</div></div><div><span>        </span><span>filetypes</span><span><span>=</span><span>filetypes</span></span></div></div><div><div><div>231</div></div><div><span><span>    </span></span><span>)</span></div></div><div><div><div>232</div></div><div>
</div></div><div><div><div>233</div></div><div><span>    </span><span>if</span><span> file_path:</span></div></div><div><div><div>234</div></div><div><span><span>        </span></span><span>entry_output.</span><span>delete</span><span>(</span><span>0</span><span><span>, tk.</span><span>END</span><span>)</span></span></div></div><div><div><div>235</div></div><div><span><span>        </span></span><span>entry_output.</span><span>insert</span><span>(</span><span>0</span><span>, file_path)</span></div></div><div><div><div>236</div></div><div>
</div></div><div><div><div>237</div></div><div><span>def</span><span> </span><span>update_size_selection</span><span>():</span></div></div><div><div><div>238</div></div><div><span>    </span><span>"""根据转换类型更新尺寸选择框的状态"""</span></div></div><div><div><div>239</div></div><div><span>    </span><span>if</span><span><span> tab_control.</span><span>index</span><span>(tab_control.</span><span>select</span><span>()) </span><span>==</span><span> </span></span><span>0</span><span>:  </span><span># 格式转换标签</span></div></div><div><div><div>240</div></div><div><span><span>        </span></span><span>conversion_type </span><span>=</span><span> conversion_var.</span><span>get</span><span>()</span></div></div><div><div><div>241</div></div><div>
</div></div><div><div><div>242</div></div><div><span>        </span><span>if</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_ico'</span><span>:</span></div></div><div><div><div>243</div></div><div><span>            </span><span># 启用尺寸选择框</span></div></div><div><div><div>244</div></div><div><span><span>            </span></span><span>frame_sizes.</span><span>pack</span><span>(</span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>, </span><span>fill</span><span>=</span><span>"x"</span><span>)</span></div></div><div><div><div>245</div></div><div><span>            </span><span>for</span><span> widget </span><span>in</span><span><span> frame_sizes.</span><span>winfo_children</span><span>():</span></span></div></div><div><div><div>246</div></div><div><span><span>                </span></span><span>widget.</span><span>configure</span><span>(</span><span>state</span><span>=</span><span>"normal"</span><span>)</span></div></div><div><div><div>247</div></div><div><span>        </span><span>else</span><span>:</span></div></div><div><div><div>248</div></div><div><span>            </span><span># 隐藏尺寸选择框</span></div></div><div><div><div>249</div></div><div><span><span>            </span></span><span>frame_sizes.</span><span>pack_forget</span><span>()</span></div></div><div><div><div>250</div></div><div><span>            </span><span>for</span><span> widget </span><span>in</span><span><span> frame_sizes.</span><span>winfo_children</span><span>():</span></span></div></div><div><div><div>251</div></div><div><span><span>                </span></span><span>widget.</span><span>configure</span><span>(</span><span>state</span><span>=</span><span>"disabled"</span><span>)</span></div></div><div><div><div>252</div></div><div><span>    </span><span>else</span><span>:  </span><span># 证件照裁切标签</span></div></div><div><div><div>253</div></div><div><span>        </span><span># 隐藏尺寸选择框</span></div></div><div><div><div>254</div></div><div><span><span>        </span></span><span>frame_sizes.</span><span>pack_forget</span><span>()</span></div></div><div><div><div>255</div></div><div><span>        </span><span>for</span><span> widget </span><span>in</span><span><span> frame_sizes.</span><span>winfo_children</span><span>():</span></span></div></div><div><div><div>256</div></div><div><span><span>            </span></span><span>widget.</span><span>configure</span><span>(</span><span>state</span><span>=</span><span>"disabled"</span><span>)</span></div></div><div><div><div>257</div></div><div>
</div></div><div><div><div>258</div></div><div><span>def</span><span> </span><span>update_custom_size_fields</span><span>():</span></div></div><div><div><div>259</div></div><div><span>    </span><span>"""更新自定义尺寸输入框的状态"""</span></div></div><div><div><div>260</div></div><div><span>    </span><span>if</span><span><span> photo_size_var.</span><span>get</span><span>() </span><span>==</span><span> </span></span><span>"自定义"</span><span>:</span></div></div><div><div><div>261</div></div><div><span><span>        </span></span><span>entry_custom_width.</span><span>config</span><span>(</span><span>state</span><span>=</span><span>"normal"</span><span>)</span></div></div><div><div><div>262</div></div><div><span><span>        </span></span><span>entry_custom_height.</span><span>config</span><span>(</span><span>state</span><span>=</span><span>"normal"</span><span>)</span></div></div><div><div><div>263</div></div><div><span>    </span><span>else</span><span>:</span></div></div><div><div><div>264</div></div><div><span><span>        </span></span><span>entry_custom_width.</span><span>config</span><span>(</span><span>state</span><span>=</span><span>"disabled"</span><span>)</span></div></div><div><div><div>265</div></div><div><span><span>        </span></span><span>entry_custom_height.</span><span>config</span><span>(</span><span>state</span><span>=</span><span>"disabled"</span><span>)</span></div></div><div><div><div>266</div></div><div>
</div></div><div><div><div>267</div></div><div><span>def</span><span> </span><span>start_conversion</span><span>():</span></div></div><div><div><div>268</div></div><div><span>    </span><span>"""开始转换或裁切"""</span></div></div><div><div><div>269</div></div><div><span><span>    </span></span><span>input_path </span><span>=</span><span> entry_input.</span><span>get</span><span>()</span></div></div><div><div><div>270</div></div><div><span><span>    </span></span><span>output_path </span><span>=</span><span> entry_output.</span><span>get</span><span>()</span></div></div><div><div><div>271</div></div><div>
</div></div><div><div><div>272</div></div><div><span>    </span><span>if</span><span> </span><span>not</span><span> input_path:</span></div></div><div><div><div>273</div></div><div><span><span>        </span></span><span>messagebox.</span><span>showerror</span><span>(</span><span>"错误"</span><span>, </span><span>"请选择输入文件"</span><span>)</span></div></div><div><div><div>274</div></div><div><span>        </span><span>return</span></div></div><div><div><div>275</div></div><div>
</div></div><div><div><div>276</div></div><div><span>    </span><span>if</span><span> </span><span>not</span><span> output_path:</span></div></div><div><div><div>277</div></div><div><span><span>        </span></span><span>messagebox.</span><span>showerror</span><span>(</span><span>"错误"</span><span>, </span><span>"请指定输出文件路径"</span><span>)</span></div></div><div><div><div>278</div></div><div><span>        </span><span>return</span></div></div><div><div><div>279</div></div><div>
</div></div><div><div><div>280</div></div><div><span>    </span><span>if</span><span><span> tab_control.</span><span>index</span><span>(tab_control.</span><span>select</span><span>()) </span><span>==</span><span> </span></span><span>0</span><span>:  </span><span># 格式转换标签</span></div></div><div><div><div>281</div></div><div><span><span>        </span></span><span>conversion_type </span><span>=</span><span> conversion_var.</span><span>get</span><span>()</span></div></div><div><div><div>282</div></div><div>
</div></div><div><div><div>283</div></div><div><span>        </span><span># 对于ICO转换，获取尺寸设置</span></div></div><div><div><div>284</div></div><div><span><span>        </span></span><span>sizes </span><span>=</span><span> []</span></div></div><div><div><div>285</div></div><div><span>        </span><span>if</span><span><span> conversion_type </span><span>==</span><span> </span></span><span>'jpg_to_ico'</span><span>:</span></div></div><div><div><div>286</div></div><div><span>            </span><span>if</span><span><span> var_16.</span><span>get</span><span>(): sizes.</span><span>append</span><span>(</span></span><span>16</span><span>)</span></div></div><div><div><div>287</div></div><div><span>            </span><span>if</span><span><span> var_32.</span><span>get</span><span>(): sizes.</span><span>append</span><span>(</span></span><span>32</span><span>)</span></div></div><div><div><div>288</div></div><div><span>            </span><span>if</span><span><span> var_48.</span><span>get</span><span>(): sizes.</span><span>append</span><span>(</span></span><span>48</span><span>)</span></div></div><div><div><div>289</div></div><div><span>            </span><span>if</span><span><span> var_64.</span><span>get</span><span>(): sizes.</span><span>append</span><span>(</span></span><span>64</span><span>)</span></div></div><div><div><div>290</div></div><div><span>            </span><span>if</span><span><span> var_128.</span><span>get</span><span>(): sizes.</span><span>append</span><span>(</span></span><span>128</span><span>)</span></div></div><div><div><div>291</div></div><div><span>            </span><span>if</span><span><span> var_256.</span><span>get</span><span>(): sizes.</span><span>append</span><span>(</span></span><span>256</span><span>)</span></div></div><div><div><div>292</div></div><div>
</div></div><div><div><div>293</div></div><div><span>            </span><span>if</span><span> </span><span>not</span><span> sizes:</span></div></div><div><div><div>294</div></div><div><span><span>                </span></span><span>messagebox.</span><span>showerror</span><span>(</span><span>"错误"</span><span>, </span><span>"请至少选择一个图标尺寸"</span><span>)</span></div></div><div><div><div>295</div></div><div><span>                </span><span>return</span></div></div><div><div><div>296</div></div><div>
</div></div><div><div><div>297</div></div><div><span>        </span><span># 执行转换</span></div></div><div><div><div>298</div></div><div><span><span>        </span></span><span>success, message </span><span>=</span><span> </span><span>convert_image</span><span>(input_path, output_path, conversion_type, sizes)</span></div></div><div><div><div>299</div></div><div>
</div></div><div><div><div>300</div></div><div><span>    </span><span>else</span><span>:  </span><span># 证件照裁切标签</span></div></div><div><div><div>301</div></div><div><span><span>        </span></span><span>photo_size </span><span>=</span><span> photo_size_var.</span><span>get</span><span>()</span></div></div><div><div><div>302</div></div><div>
</div></div><div><div><div>303</div></div><div><span>        </span><span># 获取自定义尺寸</span></div></div><div><div><div>304</div></div><div><span><span>        </span></span><span>custom_width </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>305</div></div><div><span><span>        </span></span><span>custom_height </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>306</div></div><div><span>        </span><span>if</span><span><span> photo_size </span><span>==</span><span> </span></span><span>"自定义"</span><span>:</span></div></div><div><div><div>307</div></div><div><span>            </span><span>try</span><span>:</span></div></div><div><div><div>308</div></div><div><span><span>                </span></span><span>custom_width </span><span>=</span><span> </span><span>float</span><span><span>(entry_custom_width.</span><span>get</span><span>())</span></span></div></div><div><div><div>309</div></div><div><span><span>                </span></span><span>custom_height </span><span>=</span><span> </span><span>float</span><span><span>(entry_custom_height.</span><span>get</span><span>())</span></span></div></div><div><div><div>310</div></div><div>
</div></div><div><div><div>311</div></div><div><span>                </span><span>if</span><span><span> custom_width </span><span>&lt;=</span><span> </span></span><span>0</span><span> </span><span>or</span><span><span> custom_height </span><span>&lt;=</span><span> </span></span><span>0</span><span>:</span></div></div><div><div><div>312</div></div><div><span><span>                    </span></span><span>messagebox.</span><span>showerror</span><span>(</span><span>"错误"</span><span>, </span><span>"自定义尺寸必须大于0"</span><span>)</span></div></div><div><div><div>313</div></div><div><span>                    </span><span>return</span></div></div><div><div><div>314</div></div><div><span>            </span><span>except</span><span> </span><span>ValueError</span><span>:</span></div></div><div><div><div>315</div></div><div><span><span>                </span></span><span>messagebox.</span><span>showerror</span><span>(</span><span>"错误"</span><span>, </span><span>"请输入有效的自定义尺寸"</span><span>)</span></div></div><div><div><div>316</div></div><div><span>                </span><span>return</span></div></div><div><div><div>317</div></div><div>
</div></div><div><div><div>318</div></div><div><span>        </span><span># 获取DPI设置</span></div></div><div><div><div>319</div></div><div><span>        </span><span>try</span><span>:</span></div></div><div><div><div>320</div></div><div><span><span>            </span></span><span>dpi </span><span>=</span><span> </span><span>int</span><span><span>(dpi_var.</span><span>get</span><span>())</span></span></div></div><div><div><div>321</div></div><div><span>            </span><span>if</span><span><span> dpi </span><span>&lt;=</span><span> </span></span><span>0</span><span>:</span></div></div><div><div><div>322</div></div><div><span><span>                </span></span><span>messagebox.</span><span>showerror</span><span>(</span><span>"错误"</span><span>, </span><span>"DPI必须大于0"</span><span>)</span></div></div><div><div><div>323</div></div><div><span>                </span><span>return</span></div></div><div><div><div>324</div></div><div><span>        </span><span>except</span><span> </span><span>ValueError</span><span>:</span></div></div><div><div><div>325</div></div><div><span><span>            </span></span><span>messagebox.</span><span>showerror</span><span>(</span><span>"错误"</span><span>, </span><span>"请输入有效的DPI值"</span><span>)</span></div></div><div><div><div>326</div></div><div><span>            </span><span>return</span></div></div><div><div><div>327</div></div><div>
</div></div><div><div><div>328</div></div><div><span>        </span><span># 执行裁切</span></div></div><div><div><div>329</div></div><div><span><span>        </span></span><span>success, message </span><span>=</span><span> </span><span>crop_photo</span><span>(</span></div></div><div><div><div>330</div></div><div><span><span>            </span></span><span>input_path,</span></div></div><div><div><div>331</div></div><div><span><span>            </span></span><span>output_path,</span></div></div><div><div><div>332</div></div><div><span><span>            </span></span><span>photo_size,</span></div></div><div><div><div>333</div></div><div><span><span>            </span></span><span>dpi,</span></div></div><div><div><div>334</div></div><div><span><span>            </span></span><span>custom_width,</span></div></div><div><div><div>335</div></div><div><span><span>            </span></span><span>custom_height</span></div></div><div><div><div>336</div></div><div><span><span>        </span></span><span>)</span></div></div><div><div><div>337</div></div><div>
</div></div><div><div><div>338</div></div><div><span>    </span><span>if</span><span> success:</span></div></div><div><div><div>339</div></div><div><span><span>        </span></span><span>messagebox.</span><span>showinfo</span><span>(</span><span>"成功"</span><span>, message)</span></div></div><div><div><div>340</div></div><div><span>    </span><span>else</span><span>:</span></div></div><div><div><div>341</div></div><div><span><span>        </span></span><span>messagebox.</span><span>showerror</span><span>(</span><span>"错误"</span><span>, message)</span></div></div><div><div><div>342</div></div><div>
</div></div><div><div><div>343</div></div><div><span># 创建主窗口</span></div></div><div><div><div>344</div></div><div><span><span>root </span><span>=</span><span> tk.</span><span>Tk</span><span>()</span></span></div></div><div><div><div>345</div></div><div><span><span>root.</span><span>title</span><span>(</span></span><span>"高级图像格式转换与证件照裁切工具"</span><span>)</span></div></div><div><div><div>346</div></div><div><span><span>root.</span><span>geometry</span><span>(</span></span><span>"550x600"</span><span>)</span></div></div><div><div><div>347</div></div><div><span><span>root.</span><span>resizable</span><span>(</span></span><span>False</span><span>, </span><span>False</span><span>)</span></div></div><div><div><div>348</div></div><div>
</div></div><div><div><div>349</div></div><div><span># 创建标签控件</span></div></div><div><div><div>350</div></div><div><span><span>tab_control </span><span>=</span><span> ttk.</span><span>Notebook</span><span>(root)</span></span></div></div><div><div><div>351</div></div><div>
</div></div><div><div><div>352</div></div><div><span># 格式转换标签</span></div></div><div><div><div>353</div></div><div><span><span>tab_format </span><span>=</span><span> ttk.</span><span>Frame</span><span>(tab_control)</span></span></div></div><div><div><div>354</div></div><div><span><span>tab_control.</span><span>add</span><span>(tab_format, </span></span><span>text</span><span>=</span><span>'格式转换'</span><span>)</span></div></div><div><div><div>355</div></div><div>
</div></div><div><div><div>356</div></div><div><span># 证件照裁切标签</span></div></div><div><div><div>357</div></div><div><span><span>tab_photo </span><span>=</span><span> ttk.</span><span>Frame</span><span>(tab_control)</span></span></div></div><div><div><div>358</div></div><div><span><span>tab_control.</span><span>add</span><span>(tab_photo, </span></span><span>text</span><span>=</span><span>'证件照裁切'</span><span>)</span></div></div><div><div><div>359</div></div><div>
</div></div><div><div><div>360</div></div><div><span><span>tab_control.</span><span>pack</span><span>(</span></span><span>expand</span><span>=</span><span>1</span><span>, </span><span>fill</span><span>=</span><span>'both'</span><span>, </span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>361</div></div><div>
</div></div><div><div><div>362</div></div><div><span># 格式转换标签内容</span></div></div><div><div><div>363</div></div><div><span><span>frame_conversion </span><span>=</span><span> tk.</span><span>LabelFrame</span><span>(tab_format, </span></span><span>text</span><span>=</span><span>"转换类型"</span><span>, </span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>364</div></div><div><span><span>frame_conversion.</span><span>pack</span><span>(</span></span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>, </span><span>fill</span><span>=</span><span>"x"</span><span>)</span></div></div><div><div><div>365</div></div><div>
</div></div><div><div><div>366</div></div><div><span><span>conversion_var </span><span>=</span><span> tk.</span><span>StringVar</span><span>(</span></span><span>value</span><span>=</span><span>"jpg_to_ico"</span><span>)</span></div></div><div><div><div>367</div></div><div>
</div></div><div><div><div>368</div></div><div><span><span>tk.</span><span>Radiobutton</span><span>(frame_conversion, </span></span><span>text</span><span>=</span><span>"JPG 转 ICO"</span><span>, </span><span>variable</span><span><span>=</span><span>conversion_var, </span></span><span>value</span><span>=</span><span>"jpg_to_ico"</span><span>, </span><span>command</span><span><span>=</span><span>update_size_selection).</span><span>pack</span><span>(</span></span><span>anchor</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>369</div></div><div><span><span>tk.</span><span>Radiobutton</span><span>(frame_conversion, </span></span><span>text</span><span>=</span><span>"JPG 转 PNG"</span><span>, </span><span>variable</span><span><span>=</span><span>conversion_var, </span></span><span>value</span><span>=</span><span>"jpg_to_png"</span><span>, </span><span>command</span><span><span>=</span><span>update_size_selection).</span><span>pack</span><span>(</span></span><span>anchor</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>370</div></div><div><span><span>tk.</span><span>Radiobutton</span><span>(frame_conversion, </span></span><span>text</span><span>=</span><span>"PNG 转 JPG"</span><span>, </span><span>variable</span><span><span>=</span><span>conversion_var, </span></span><span>value</span><span>=</span><span>"png_to_jpg"</span><span>, </span><span>command</span><span><span>=</span><span>update_size_selection).</span><span>pack</span><span>(</span></span><span>anchor</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>371</div></div><div>
</div></div><div><div><div>372</div></div><div><span># 文件选择框架</span></div></div><div><div><div>373</div></div><div><span><span>frame_files </span><span>=</span><span> tk.</span><span>LabelFrame</span><span>(tab_format, </span></span><span>text</span><span>=</span><span>"文件选择"</span><span>, </span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>374</div></div><div><span><span>frame_files.</span><span>pack</span><span>(</span></span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>, </span><span>fill</span><span>=</span><span>"x"</span><span>)</span></div></div><div><div><div>375</div></div><div>
</div></div><div><div><div>376</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_files, </span></span><span>text</span><span>=</span><span>"输入文件:"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>377</div></div><div><span><span>entry_input </span><span>=</span><span> tk.</span><span>Entry</span><span>(frame_files, </span></span><span>width</span><span>=</span><span>40</span><span>)</span></div></div><div><div><div>378</div></div><div><span><span>entry_input.</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>379</div></div><div><span><span>tk.</span><span>Button</span><span>(frame_files, </span></span><span>text</span><span>=</span><span>"浏览..."</span><span>, </span><span>command</span><span><span>=</span><span>select_input_file).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>2</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>380</div></div><div>
</div></div><div><div><div>381</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_files, </span></span><span>text</span><span>=</span><span>"输出文件:"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>382</div></div><div><span><span>entry_output </span><span>=</span><span> tk.</span><span>Entry</span><span>(frame_files, </span></span><span>width</span><span>=</span><span>40</span><span>)</span></div></div><div><div><div>383</div></div><div><span><span>entry_output.</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>384</div></div><div><span><span>tk.</span><span>Button</span><span>(frame_files, </span></span><span>text</span><span>=</span><span>"浏览..."</span><span>, </span><span>command</span><span><span>=</span><span>select_output_file).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>2</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>385</div></div><div>
</div></div><div><div><div>386</div></div><div><span># 尺寸选择框架（初始隐藏，仅在JPG转ICO时显示）</span></div></div><div><div><div>387</div></div><div><span><span>frame_sizes </span><span>=</span><span> tk.</span><span>LabelFrame</span><span>(tab_format, </span></span><span>text</span><span>=</span><span>"图标尺寸"</span><span>, </span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>388</div></div><div>
</div></div><div><div><div>389</div></div><div><span><span>var_16 </span><span>=</span><span> tk.</span><span>BooleanVar</span><span>(</span></span><span>value</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>390</div></div><div><span><span>var_32 </span><span>=</span><span> tk.</span><span>BooleanVar</span><span>(</span></span><span>value</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>391</div></div><div><span><span>var_48 </span><span>=</span><span> tk.</span><span>BooleanVar</span><span>(</span></span><span>value</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>392</div></div><div><span><span>var_64 </span><span>=</span><span> tk.</span><span>BooleanVar</span><span>(</span></span><span>value</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>393</div></div><div><span><span>var_128 </span><span>=</span><span> tk.</span><span>BooleanVar</span><span>(</span></span><span>value</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>394</div></div><div><span><span>var_256 </span><span>=</span><span> tk.</span><span>BooleanVar</span><span>(</span></span><span>value</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>395</div></div><div>
</div></div><div><div><div>396</div></div><div><span><span>tk.</span><span>Checkbutton</span><span>(frame_sizes, </span></span><span>text</span><span>=</span><span>"16x16"</span><span>, </span><span>variable</span><span><span>=</span><span>var_16).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>397</div></div><div><span><span>tk.</span><span>Checkbutton</span><span>(frame_sizes, </span></span><span>text</span><span>=</span><span>"32x32"</span><span>, </span><span>variable</span><span><span>=</span><span>var_32).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>398</div></div><div><span><span>tk.</span><span>Checkbutton</span><span>(frame_sizes, </span></span><span>text</span><span>=</span><span>"48x48"</span><span>, </span><span>variable</span><span><span>=</span><span>var_48).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>2</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>399</div></div><div><span><span>tk.</span><span>Checkbutton</span><span>(frame_sizes, </span></span><span>text</span><span>=</span><span>"64x64"</span><span>, </span><span>variable</span><span><span>=</span><span>var_64).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>400</div></div><div><span><span>tk.</span><span>Checkbutton</span><span>(frame_sizes, </span></span><span>text</span><span>=</span><span>"128x128"</span><span>, </span><span>variable</span><span><span>=</span><span>var_128).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>401</div></div><div><span><span>tk.</span><span>Checkbutton</span><span>(frame_sizes, </span></span><span>text</span><span>=</span><span>"256x256"</span><span>, </span><span>variable</span><span><span>=</span><span>var_256).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>2</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>)</span></div></div><div><div><div>402</div></div><div>
</div></div><div><div><div>403</div></div><div><span># 证件照裁切标签内容</span></div></div><div><div><div>404</div></div><div><span><span>frame_photo_size </span><span>=</span><span> tk.</span><span>LabelFrame</span><span>(tab_photo, </span></span><span>text</span><span>=</span><span>"证件照尺寸"</span><span>, </span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>405</div></div><div><span><span>frame_photo_size.</span><span>pack</span><span>(</span></span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>, </span><span>fill</span><span>=</span><span>"x"</span><span>)</span></div></div><div><div><div>406</div></div><div>
</div></div><div><div><div>407</div></div><div><span><span>photo_size_var </span><span>=</span><span> tk.</span><span>StringVar</span><span>(</span></span><span>value</span><span>=</span><span>"一寸"</span><span>)</span></div></div><div><div><div>408</div></div><div><span><span>photo_sizes </span><span>=</span><span> </span></span><span>list</span><span><span>(</span><span>PHOTO_SIZES</span><span>.</span><span>keys</span><span>())</span></span></div></div><div><div><div>409</div></div><div>
</div></div><div><div><div>410</div></div><div><span><span>size_dropdown </span><span>=</span><span> ttk.</span><span>Combobox</span><span>(frame_photo_size, </span></span><span>textvariable</span><span><span>=</span><span>photo_size_var, </span></span><span>values</span><span><span>=</span><span>photo_sizes, </span></span><span>state</span><span>=</span><span>"readonly"</span><span>)</span></div></div><div><div><div>411</div></div><div><span><span>size_dropdown.</span><span>pack</span><span>(</span></span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>412</div></div><div><span><span>size_dropdown.</span><span>bind</span><span>(</span></span><span>'&lt;&lt;ComboboxSelected&gt;&gt;'</span><span>, </span><span>lambda</span><span> </span><span>e</span><span><span>: </span><span>update_custom_size_fields</span><span>())</span></span></div></div><div><div><div>413</div></div><div>
</div></div><div><div><div>414</div></div><div><span># 自定义尺寸框架</span></div></div><div><div><div>415</div></div><div><span><span>frame_custom_size </span><span>=</span><span> tk.</span><span>LabelFrame</span><span>(tab_photo, </span></span><span>text</span><span>=</span><span>"自定义尺寸 (毫米)"</span><span>, </span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>416</div></div><div><span><span>frame_custom_size.</span><span>pack</span><span>(</span></span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>, </span><span>fill</span><span>=</span><span>"x"</span><span>)</span></div></div><div><div><div>417</div></div><div>
</div></div><div><div><div>418</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_custom_size, </span></span><span>text</span><span>=</span><span>"宽度:"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>419</div></div><div><span><span>entry_custom_width </span><span>=</span><span> tk.</span><span>Entry</span><span>(frame_custom_size, </span></span><span>width</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>420</div></div><div><span><span>entry_custom_width.</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>421</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_custom_size, </span></span><span>text</span><span>=</span><span>"毫米"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>2</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>422</div></div><div>
</div></div><div><div><div>423</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_custom_size, </span></span><span>text</span><span>=</span><span>"高度:"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>424</div></div><div><span><span>entry_custom_height </span><span>=</span><span> tk.</span><span>Entry</span><span>(frame_custom_size, </span></span><span>width</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>425</div></div><div><span><span>entry_custom_height.</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>426</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_custom_size, </span></span><span>text</span><span>=</span><span>"毫米"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>2</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>427</div></div><div>
</div></div><div><div><div>428</div></div><div><span># DPI设置框架</span></div></div><div><div><div>429</div></div><div><span><span>frame_dpi </span><span>=</span><span> tk.</span><span>LabelFrame</span><span>(tab_photo, </span></span><span>text</span><span>=</span><span>"DPI 设置"</span><span>, </span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>430</div></div><div><span><span>frame_dpi.</span><span>pack</span><span>(</span></span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>, </span><span>fill</span><span>=</span><span>"x"</span><span>)</span></div></div><div><div><div>431</div></div><div>
</div></div><div><div><div>432</div></div><div><span><span>dpi_var </span><span>=</span><span> tk.</span><span>StringVar</span><span>(</span></span><span>value</span><span>=</span><span>"300"</span><span>)</span></div></div><div><div><div>433</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_dpi, </span></span><span>text</span><span>=</span><span>"每英寸点数:"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>434</div></div><div><span><span>entry_dpi </span><span>=</span><span> tk.</span><span>Entry</span><span>(frame_dpi, </span></span><span>textvariable</span><span><span>=</span><span>dpi_var, </span></span><span>width</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>435</div></div><div><span><span>entry_dpi.</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>436</div></div><div>
</div></div><div><div><div>437</div></div><div><span># 文件选择框架（证件照）</span></div></div><div><div><div>438</div></div><div><span><span>frame_photo_files </span><span>=</span><span> tk.</span><span>LabelFrame</span><span>(tab_photo, </span></span><span>text</span><span>=</span><span>"文件选择"</span><span>, </span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>10</span><span>)</span></div></div><div><div><div>439</div></div><div><span><span>frame_photo_files.</span><span>pack</span><span>(</span></span><span>padx</span><span>=</span><span>10</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>, </span><span>fill</span><span>=</span><span>"x"</span><span>)</span></div></div><div><div><div>440</div></div><div>
</div></div><div><div><div>441</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_photo_files, </span></span><span>text</span><span>=</span><span>"输入文件:"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>442</div></div><div><span><span>entry_photo_input </span><span>=</span><span> tk.</span><span>Entry</span><span>(frame_photo_files, </span></span><span>width</span><span>=</span><span>40</span><span>)</span></div></div><div><div><div>443</div></div><div><span><span>entry_photo_input.</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>444</div></div><div><span><span>tk.</span><span>Button</span><span>(frame_photo_files, </span></span><span>text</span><span>=</span><span>"浏览..."</span><span>, </span><span>command</span><span><span>=</span><span>select_input_file).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>0</span><span>, </span><span>column</span><span>=</span><span>2</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>445</div></div><div>
</div></div><div><div><div>446</div></div><div><span><span>tk.</span><span>Label</span><span>(frame_photo_files, </span></span><span>text</span><span>=</span><span>"输出文件:"</span><span><span>).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>0</span><span>, </span><span>sticky</span><span>=</span><span>"w"</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>447</div></div><div><span><span>entry_photo_output </span><span>=</span><span> tk.</span><span>Entry</span><span>(frame_photo_files, </span></span><span>width</span><span>=</span><span>40</span><span>)</span></div></div><div><div><div>448</div></div><div><span><span>entry_photo_output.</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>1</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>449</div></div><div><span><span>tk.</span><span>Button</span><span>(frame_photo_files, </span></span><span>text</span><span>=</span><span>"浏览..."</span><span>, </span><span>command</span><span><span>=</span><span>select_output_file).</span><span>grid</span><span>(</span></span><span>row</span><span>=</span><span>1</span><span>, </span><span>column</span><span>=</span><span>2</span><span>, </span><span>padx</span><span>=</span><span>5</span><span>, </span><span>pady</span><span>=</span><span>5</span><span>)</span></div></div><div><div><div>450</div></div><div>
</div></div><div><div><div>451</div></div><div><span># 转换按钮</span></div></div><div><div><div>452</div></div><div><span><span>btn_convert </span><span>=</span><span> tk.</span><span>Button</span><span>(root, </span></span><span>text</span><span>=</span><span>"开始处理"</span><span>, </span><span>command</span><span><span>=</span><span>start_conversion, </span></span><span>bg</span><span>=</span><span>"#4CAF50"</span><span>, </span><span>fg</span><span>=</span><span>"white"</span><span>, </span><span>font</span><span><span>=</span><span>(</span></span><span>"Arial"</span><span>, </span><span>12</span><span>))</span></div></div><div><div><div>453</div></div><div><span><span>btn_convert.</span><span>pack</span><span>(</span></span><span>pady</span><span>=</span><span>20</span><span>)</span></div></div><div><div><div>454</div></div><div>
</div></div><div><div><div>455</div></div><div><span># 初始化界面</span></div></div><div><div><div>456</div></div><div><span><span>update_size_selection</span><span>()</span></span></div></div><div><div><div>457</div></div><div><span><span>update_custom_size_fields</span><span>()</span></span></div></div><div><div><div>458</div></div><div>
</div></div><div><div><div>459</div></div><div><span># 启动主循环</span></div></div><div><div><div>460</div></div><div><span><span>root.</span><span>mainloop</span><span>()</span></span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.levek.top/posts/radxa_a7z/radxa_a7z/</id>
      <title type="text">Radxa A7Z 外壳设计</title>
      <published>2025-11-08T00:00:00.000Z</published>
      <updated>2025-12-08T00:00:00.000Z</updated>
      <author><name>levek</name></author>
      <link rel="alternate" href="https://blog.levek.top/posts/radxa_a7z/radxa_a7z/"/>
      <summary type="text">瑞莎A7Z的外壳，建立风道，降低CPU核心温度，适配最新版本。</summary>
      <content type="html"><![CDATA[<section><h1>模型文件设计思路<a href="#模型文件设计思路"><span>#</span></a></h1><p>这个外壳以4010 双滚珠风扇为核心散热设计，搭配利落的长方体外观，整体风格简约大气，没有多余装饰，兼顾颜值与实用性。机身轻巧便携，彻底打破传统办公设备的携带束缚，外出办公时无需繁琐收纳，只需带上主机和一台 Pad，通过 VNC 连接即可快速投屏显示，随时随地搭建起高效办公场景。</p><p>编程调试方面，设备支持 VS code for Linux，操作流畅无卡顿，代码编写、语法校验、实时调试等功能一应俱全，为开发者提供便捷顺手的编程环境。办公软件体验更是拉满，预装 PC 级 WPS、OFFICE 套件，无论是复杂表格制作、专业文档编辑，还是精美演示文稿设计，都能轻松应对，操作逻辑与电脑端高度一致，极大提升办公效率与使用舒适度，满足日常办公的全场景需求。</p></section>
<section><h1>3D渲染图片<a href="#3d渲染图片"><span>#</span></a></h1><p></p><figure><img alt="React Hooks示例" loading="lazy" width="1248" height="832" src="/_astro/radxa3.CiZvSUbo_MPujy.webp" /><figcaption>React Hooks示例</figcaption></figure>
<figure><img alt="React Hooks示例" loading="lazy" width="1248" height="832" src="/_astro/radxa4.BLQ9nX4W_Z1ylo4F.webp" /><figcaption>React Hooks示例</figcaption></figure><p></p></section>
<section><h1>实物外观<a href="#实物外观"><span>#</span></a></h1><p></p><figure><img alt="React Hooks示例" loading="lazy" width="3182" height="2386" src="/_astro/radxa2.DQoBKleb_Z26knPc.webp" /><figcaption>React Hooks示例</figcaption></figure><p></p><section><h2>Bilibili<a href="#bilibili"><span>#</span></a></h2> <hr /></section><section><h2>🌟 下载方式<a href="#-下载方式"><span>#</span></a></h2><hr /><ul>
<li><strong>直接下载</strong>: <a href="https://ghfast.top/github.com/levek-lcd/radxa_A7z_hull/releases/download/zip/A7Z.zip" target="_blank">radxa_A7z外壳</a></li>
</ul><hr /></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.levek.top/posts/guide/first_article/</id>
      <title type="text">声明</title>
      <published>2025-11-02T00:00:00.000Z</published>
      <updated>2025-11-02T00:00:00.000Z</updated>
      <author><name>levek</name></author>
      <link rel="alternate" href="https://blog.levek.top/posts/guide/first_article/"/>
      <summary type="text">网站声明</summary>
      <content type="html"><![CDATA[<section><h2>🌟 项目概述<a href="#-项目概述"><span>#</span></a></h2><hr /><p><strong>levek-Blog</strong>是基于Firefly模板进行二次创作建立的个人博客网站。</p><p><strong>Firefly</strong> 是一款基于 Astro 框架开发的清新美观且现代化个人博客主题，专为技术爱好者和内容创作者设计。该主题融合了现代 Web 技术栈，提供了丰富的功能模块和高度可定制的界面，让您能够轻松打造出专业且美观的个人博客网站。</p><hr /></section>
<section><h2>🌟 项目建立时间<a href="#-项目建立时间"><span>#</span></a></h2><p>网站于2025-11-02建立成功！</p></section>
<section><h2>本网站提供的所有教程仅供学习使用，无任何商务用途!<a href="#本网站提供的所有教程仅供学习使用无任何商务用途"><span>#</span></a></h2></section>]]></content>
    </entry>
</feed>
