Python 三方库鸿蒙化适配 PC 完整迁移实战
一、前言
最近做了鸿蒙PC工作台的项目,使用了很多C和Python的库,并且也结合了AI相关的技术进行赋能增强。接下来梳理Python 三方库鸿蒙化的一些经验分享。
首先Python 三方库鸿蒙化,不是把 Python 代码翻译成 ArkTS,而是让成熟 Python 能力适配 HarmonyOS PC 的运行时、二进制环境、应用沙箱和 ArkTS 调用链。
对 Python 三方库迁移来说,PC 不是"手机屏幕放大",而是更接近桌面生产力场景。
还有就是鸿蒙 PC 和鸿蒙手机开发有什么区别,两者共享 ArkTS、Stage 模型、DevEco Studio、权限和沙箱等基础,但应用形态和迁移侧重点不同,很多人认为鸿蒙PC和鸿蒙手机开发是两个东西,这是不对的,但是认为没什么区别只是改改UI,这也不对,今天把开发概念也和大家普及一下:
1、首先是交互方式的不同 ,鸿蒙手机触控、手势、竖屏单任务体验。鸿蒙PC鼠标、键盘、窗口、多任务和大屏布局。HarmonyOS在框架基础上做了优化,很大程度上我们不需要太多精力适配这一层。但是独特的交互体验上,鸿蒙PC的效果就需要单独逻辑的适配,比如在 PC 上要支持文件选择、拖拽、预览区、进度状态,而不是只做一个按钮。
2、任务形态不同,鸿蒙手机开发更关注短任务、前后台切换、功耗和热管理更敏感。鸿蒙 PC 开发更关注长任务、批处理、桌面级预览和可取消任务更常见。所以图片处理、模型加载、批量转换都要走异步 N-API,并设计取消、超时、日志。
3、文件使用习惯不同 ,鸿蒙手机开发更关注更多通过相册、媒体库、应用内数据流转。鸿蒙 PC 开发更关注更常见本地文件、工作目录、批量文件和用户选择路径。所以Python 层不能假设传统 PC 任意路径可读写,ArkTS 必须处理授权路径并传给 Native。
当然还有界面布局、内存和性能消耗的应用处理、功能操控和呈现的差异化处理等细节。
二、Python 三方库到底包含什么
要搞清楚Python 三方库鸿蒙化适配流程,首先要清楚三方库包里有什么,哪些需要迁移的时候做适配工作,很多人以为三方库就是一堆 .py 文件,所以才会误判"换个源安装一下就行"。但其实不然,例如 Pillow-12.2.0-cp312-cp312-manylinux_2_17_x86_64.whl 这个标签表示 CPython 3.12、Linux、x86_64,鸿蒙用不了,必须重新编译成 ohos_aarch64 标签:
Python 三方库不只是 .py文件,还可能包含 Native 扩展、动态库、资源和构建元数据。 迁移到鸿蒙 PC 需要适配运行时、ABI、沙箱和应用调用链。
很多 Python 三方库不只有 .py 文件,还可能包含: 1、C/C++ 编译出来的二进制扩展,比如 .so 2、底层依赖库,比如 libjpeg、zlib 3、资源文件,比如模型、字体、证书、配置 4、构建脚本和平台判断逻辑 5、wheel 包里的 ABI、Python 版本、平台标签
三、Python 三方库适配迁移的流程 
1、PC Python 库 分析 PyPI 包、源码、依赖树、C 扩展、资源文件和业务调用 API。判断库是否纯 Python:下载 wheel 后看是否含 none-any 标签,或解压后是否有 .so 文件。纯 Python 库直接复制即可,带 C 扩展的才需要走 2-5 步。 2、鸿蒙化构建 使用目标 Python 运行时、NDK、sysroot 和依赖库生成 ohos 产物。 3、wheel / so 产物 输出可安装 wheel(Python 官方的二进制包格式)、Native 动态库、资源目录、manifest 和补丁。 4、应用集成链 ArkTS 页面调用 N-API,Native 层初始化 CPython 并执行 Python 入口。 5、真实验收 在 HarmonyOS PC 应用里完成图片处理、错误回传、日志和升级验证。
四、实战操作Pillow 鸿蒙化适配 企业里的运营、行政、销售、培训同学经常要处理图片:报销凭证要压缩,活动素材要统一尺寸,门店巡检照片要加水印,合同附件图片要转成统一格式。过去这些动作可能依赖在线工具、PS 或人工批处理,效率低,也不方便在内网环境中沉淀成标准流程。
我们鸿蒙 PC 桌面应用有个功能:用户拖入图片或选择文件夹,设置输出尺寸、水印文字和格式,点击"生成交付图"。应用在本地完成处理,输出统一规格的图片和处理结果清单。
4.1 Pillow 负责什么
Pillow 是 Python 里处理图片的头号工具库,Pillow 负责什么 打开图片、读取元信息、缩放裁剪、格式转换、绘制水印、保存输出文件。这些能力已经成熟,不必在 Native 层重新造一套。
鸿蒙应用负责提供文件选择、权限、进度、预览、错误提示和沙箱目录管理,把图片处理能力包装成用户能点击的工作流。
4.2 诊断脚本:先看 Pillow 支持什么
python
import importlib.metadata as metadata
import sys
from pathlib import Path
from PIL import Image, features
def main():
print("python:", sys.version)
print("pillow:", metadata.version("Pillow"))
print("pillow file:", Image.__file__)
print("jpeg support:", features.check("jpg"))
print("png support:", features.check("png"))
print("zlib support:", features.check("zlib")) # PNG 的压缩依赖
print("freetype support:", features.check("freetype2"))
samples = [
Path("samples/input-small.jpg"),
Path("samples/input-alpha.png"),
Path("samples/input-large.jpg"),
]
for sample in samples:
with Image.open(sample) as image:
print(sample, image.format, image.mode, image.size)
if __name__ == "__main__":
main()
上面的脚本用于说明应该看三方库什么部分需要关注,不表示本机已经安装了鸿蒙 Python 或已经完成交叉编译。实际项目要把命令放进 notes.md,并记录运行环境、输入样本和输出结果。
4.3 完整架构
python
├─ ArkTS 页面
│ 负责按钮、文件选择、预览、状态展示
│
├─ Native / N-API 桥接层
│ 负责 ArkTS 调 C/C++,异步执行任务
│
├─ CPython 运行时
│ 让应用里能运行 Python 代码
│
├─ Python 业务代码
│ 比如 app_image_pipeline.py
│
├─ Pillow
│ 提供 Image.open、resize、save、水印等图片处理能力
│
└─ Native 依赖
比如 _imaging.so、libjpeg、libpng、zlib 等
全流程如上所示:HarmonyOS 可运行的 Python + Pillow + Native 依赖集成方案,然后把它打进 HarmonyOS 应用里。
4.4 需要关注的七个细节
1、CPython 要能在 HarmonyOS 上运行 2、Pillow 的 C 扩展要按 HarmonyOS ABI 编译 3、libjpeg / libpng / zlib 等依赖也要是 HarmonyOS 可加载版本 4、动态库路径要让应用运行时找得到 5、Python 的 sys.path 要指向应用里的 Python 包目录 6、图片输入输出路径要符合 HarmonyOS 应用沙箱 7、ArkTS 调用 Python 处理图片时要走异步,避免 UI 卡死
4.5 快速判断流程:

五、改动应该放在哪里:别把所有问题都改进三方库源码
迁移工程要分清"改库""改构建""改应用""改验证"。这样后续升级 Pillow 或替换库时,才不会一团乱。
| 改动位置 | 适合放什么 | 不适合放什么 | 交付物 |
|---|---|---|---|
| 三方库补丁 | 平台判断、编译宏、缺失函数兼容、明确的上游适配点 | 业务路径、应用 UI、临时调试开关 | patches/*.patch、补丁说明 |
| 构建脚本 | NDK、sysroot、依赖库路径、构建开关、wheel 产物归档 | 业务逻辑、运行时动态路径猜测 | build_pillow_for_ohos.sh、构建日志 |
| 应用工程 | ArkTS 页面、权限、文件选择、N-API 异步接口、沙箱目录 | 三方库内部实现和算法改造 | 最小 Demo、接口说明 |
| Python 业务封装 | 稳定业务函数、参数校验、结果结构、异常边界 | ArkTS UI 状态、Native 生命周期管理 | app_image_pipeline.py |
| 验证材料 | 金样例、性能基线、错误样例、排障记录 | 只存在个人机器上的临时命令 | golden tests、notes.md |
5.1 每个迁移包都要留下身份信息:manifest.yaml
yaml
package: Pillow
version: 12.2.0
target:
platform: harmonyos-pc
abi: ohos-aarch64
python: cp312
purpose:
- open_jpeg
- open_png
- resize_preview
- save_png
dependencies:
native:
- libjpeg
- libpng
- zlib
python:
- app_image_pipeline.py
artifacts:
wheel: dist/Pillow-12.2.0-cp312-cp312-ohos_aarch64.whl
patches: patches/
notes: notes.md
limits:
max_preview_size: 960 # 预览图最大尺寸,单位像素
run_in_ui_thread: false # Python 处理是否在 UI 线程,必须为 false
supported_formats: [jpg, png] # 明确支持格式
max_batch_size: 50 # 批量处理上限,防内存爆
5.2 构建脚本模板
bash
#!/usr/bin/env bash
set -euo pipefail
export OHOS_SDK_HOME="${OHOS_SDK_HOME:-/path/to/ohos-sdk}"
export PROJECT_ROOT="${PROJECT_ROOT:-$(pwd)}"
export SYSROOT="$OHOS_SDK_HOME/native/sysroot"
export CC="$OHOS_SDK_HOME/native/llvm/bin/clang"
export CXX="$OHOS_SDK_HOME/native/llvm/bin/clang++"
export AR="$OHOS_SDK_HOME/native/llvm/bin/llvm-ar"
export CFLAGS="--target=aarch64-linux-ohos --sysroot=$SYSROOT -fPIC"
export LDFLAGS="--target=aarch64-linux-ohos --sysroot=$SYSROOT"
# 从源码编译 Pillow wheel
python -m pip wheel Pillow==12.2.0 \
--no-binary Pillow \
--no-deps \
--wheel-dir "$PROJECT_ROOT/dist" \
--config-settings=build-option=--enable-zlib \
--config-settings=build-option=--enable-jpeg \
--config-settings=build-option=--disable-tiff \
--config-settings=build-option=--disable-webp
# 验证 wheel 标签
python "$PROJECT_ROOT/tools/check_wheel_tag.py" "$PROJECT_ROOT/dist"/*Pillow*.whl
典型补丁点:
- 平台判断:不要把
ohos当成普通 Linux 全量处理 - 动态库查找:避免运行时硬编码开发机路径
- 资源路径:字体、图片和临时文件要进入应用沙箱
- 构建开关:先关闭不需要的格式支持,降低第一阶段复杂度
不要做的事:
- 不要为了"看起来完整"一次迁所有 codec
- 不要只验证
import,不跑图片读写 - 不要把模型、图片样本和测试数据塞进最终应用包
- 不要让 ArkTS UI 线程直接等 Python 处理完成
六、GUI 库的特殊情况
重要更新:C++ Qt 已支持 HarmonyOS NEXT(Qt For OpenHarmony Alpha v8,基于 Qt5.15.12),但 Python 的 Qt 绑定(PySide/PyQt)官方尚未支持。
| GUI 库 | 鸿蒙支持状态 | 说明 |
|---|---|---|
| tkinter | ❌ 不可用 | 依赖 Tcl/Tk,需要 X11,鸿蒙没有 |
| PyQt5/PySide2 | ⚠️ 理论上可能,但没人做 | Qt5 已支持鸿蒙,但 Python 绑定未移植 |
| PyQt6/PySide6 | ❌ 不可用 | 鸿蒙没有 Qt6 支持 |
| matplotlib 交互式 | ❌ 不能弹窗 | 没有 GUI 后端 |
| matplotlib 非交互式 | ✅ 可用 | Agg 后端生成文件,ArkTS 展示 |
结论:Python 层不要做 GUI 弹窗,图片处理结果通过文件输出,由 ArkTS 页面展示。
python
# 正确做法:生成文件,不弹窗
import matplotlib
matplotlib.use('Agg') # 必须在导入 pyplot 之前
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [4, 5, 6])
plt.savefig('/data/local/tmp/chart.png') # 保存到沙箱
# 不要调用 plt.show()
typescript
// ArkTS 展示
Image('/data/local/tmp/chart.png')
.width(300)
.height(200)
七、社区资源与验证路径
7.1 社区 Python 移植方案
| 方案 | Python 版本 | 特点 | 地址 |
|---|---|---|---|
| OpenHarmony_Python | 3.13.5 | 官方集成到固件 | gitee.com/OpenHarmony_Python/python_oh |
| oh-edu-python | 3.12.12 | 预编译二进制 + 包管理器 | github.com/SSRVodka/oh-edu-python |
| oh-edu-pkgs | - | 包含 Pillow 等库的构建脚本 | github.com/SSRVodka/oh-edu-pkgs |
| langchain-on-openharmony | 3.11.11 | 3 条命令快速部署 | github.com/lmxxf/langchain-on-openharmony |
7.2 推荐验证路径
csharp
第 1 天:跑通 langchain-on-openharmony 的 Python Demo
↓ 确认 Python 能在设备上跑
第 2-3 天:用 oh-edu-pkgs 编译 Pillow
↓ 确认 Pillow 能编译出来
第 4-5 天:写最小 N-API 桥接,ArkTS 调 Python 处理一张图
↓ 确认全链路跑通
第 6-10 天:完善功能、优化性能、处理边界情况
↓ 生产就绪
决策点:如果第 2-3 天 Pillow 编译失败,建议果断评估投入产出比,考虑:
- 用鸿蒙原生图像 API 替代 Pillow(功能弱但零移植成本)
- 切服务端方案(最稳妥)
- 找社区支持或商业支持
7.3 关键验证命令
bash
# 1. 验证 Python 运行时
hdc shell '/data/local/tmp/python-home/bin/python3.12 -c "import sys; print(sys.version)"'
# 2. 验证 Pillow 安装
hdc shell '
export LD_LIBRARY_PATH=/data/local/tmp/libs
export PYTHONHOME=/data/local/tmp/python-home
python3.12 -c "from PIL import Image; print(Image.__version__)"
'
# 3. 验证图片处理
hdc shell '
export LD_LIBRARY_PATH=/data/local/tmp/libs
export PYTHONHOME=/data/local/tmp/python-home
python3.12 -c "
from PIL import Image
img = Image.new(\'RGB\', (100, 100), color=\'red\')
img.save(\'/data/local/tmp/test.png\')
print(\'Image created: OK\')
"
'
# 4. 验证 N-API 桥接(在 ArkTS 应用内测试)
# 调用 processImage(),检查返回路径和文件是否存在
八、总结
Python 三方库鸿蒙化适配的核心是判断库的类型,选择正确的迁移策略:
| 库类型 | 判断方法 | 迁移工作量 | 策略 |
|---|---|---|---|
| 纯 Python | none-any.whl,无 .so |
1 天 | 直接复制 |
| 带 C 扩展 | 有 .so,平台标签 |
1-2 周 | 交叉编译 |
| 依赖系统库 | ldd 看依赖 |
看库 availability | 额外移植 |
| GUI 库 | 导入 tkinter/Qt | 不可用 | 用 ArkTS 替代 UI |
关键原则:
- 别把所有问题都改进三方库源码,分清楚改库、改构建、改应用、改验证
- 先验证最小可用集,再逐步加功能
- 所有 IO 走沙箱,所有 Python 调用走异步
- 留下 manifest 和验证材料,方便后续升级和排障