[鸿蒙三方库适配实战] 图像处理框架 G‘MIC CLI 的 OpenHarmony 平台迁移实践
[鸿蒙三方库适配实战] 图像处理框架 G’MIC CLI 的 OpenHarmony 平台迁移实践
摘要:本文详细介绍了如何将功能全面的开源数字图像处理框架 G’MIC CLI 适配到 鸿蒙PC 平台。文章将系统性地讲解如何利用 lycium_plusplus 构建框架,处理 C/C++ 项目在鸿蒙环境下的交叉编译流程,展示如何处理 OpenMP 运行时依赖、zlib 标准库解压支持、CImg 头文件管理以及 HNP 包生成的完整实践。
本文是软件鸿蒙化迁移实践系列文章之一,专注于 C/C++ 原生库的鸿蒙 PC 适配,为开发者提供完整的迁移指南。
GitCode 仓库地址:https://atomgit.com/weixin_62765017/ohos_gmic
欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/
项目信息说明
| 项目 | 说明 |
|---|---|
| 名称 | G’MIC CLI |
| 开源协议 | CeCILL-C |
| 源码版本 | 3.5.0 |
| 目标平台 | 鸿蒙 PC |
| 依赖项 | CMake, CImg, zlib |
| 操作系统平台 | WSL Ubuntu 24.04 |
一、背景介绍
1.0 功能与效果
G’MIC CLI 在本实践中的预期能力如下:
功能:提供功能全面的数字图像处理功能,支持 1000+ 图像滤镜和处理命令,包括色彩调整、几何变换、滤镜效果、图像分析、格式转换等核心功能。
效果:在鸿蒙 PC 上提供与标准 Linux 环境相近的 G’MIC CLI 使用体验,便于在鸿蒙应用开发中实现批量图像处理、自动化滤镜应用、图像格式转换等场景的图像处理功能。
1.1 什么是 OpenHarmony HNP 生态
HNP(Harmony Native Package)是 OpenHarmony 的原生包格式,lycium 是增强型构建框架,支持自动下载源码、交叉编译(arm64-v8a、armeabi-v7a)、一键生成 HNP 包以及开源声明聚合(OAT.xml)。C/C++ 原生库的适配是鸿蒙系统生态建设中的重要一环。
1.2 为什么适配 C/C++ 原生库会有难度
常见挑战包括:
- 构建系统差异:C/C++ 项目通常使用 CMake、Autotools 等构建系统,需要配置交叉编译工具链(aarch64-linux-ohos-clang/clang++)。
- OpenMP 运行时依赖:启用 OpenMP 并行计算后,运行时依赖 libomp.so 动态库,鸿蒙系统默认未提供。
- zlib 标准库支持:G’MIC 标准库(gmic_stdlib.gmic)需要 zlib 解压支持,需要正确配置 zlib 路径。
- 头文件管理:G’MIC 依赖 CImg.h 模板库(70443 行,3.4MB),需要正确包含在源码中。
- 标准库文件分发:gmic_stdlib.gmic 需要随包发布到 /usr/share/gmic/ 目录。
- 构建缓存问题:lycium 使用 hpk_build.csv 跟踪构建状态,需要正确清理缓存才能重新构建。
1.3 G’MIC 简介
G’MIC(GREYC’s Magic for Image Computing)是一个由 David Tschumperlé 开发的功能全面的开源数字图像处理框架。其主要特点包括:
- 丰富的滤镜库:提供 1000+ 图像处理命令和滤镜效果。
- 命令行接口:提供强大的 CLI 工具,支持脚本化和批处理。
- CImg 核心:基于 CImg C++ 图像处理模板库,轻量且高效。
- 跨平台特性:原生支持 Windows、macOS、Linux,本次适配扩展到 OpenHarmony 平台。
- 开源地址:
- GitHub: https://github.com/GreycLab/gmic
- GitCode: https://gitcode.com/weixin_62765017/gmic
二、环境准备
2.0 系统要求
- 开发环境:Ubuntu 24.04(推荐 WSL 2)
- 核心工具:CMake(v3.16+)、GCC/G++、Git
- 构建框架:lycium_plusplus
- 鸿蒙 SDK:OpenHarmony SDK(提供交叉编译工具链 aarch64-linux-ohos-clang/clang++)
- 目标架构:arm64-v8a(AArch64)
2.0.1 扩展阅读与参考教程
下方汇总展示了多位老师在鸿蒙 OpenHarmony 适配方面的高质量教程。若在前提准备(环境、工具链、框架)部分还有不清楚的地方,可参考这些文章进一步学习。 以下资源不分先后顺序,均具有参考价值。
| 资源类型 | 描述 | 链接 |
|---|---|---|
| 三方库交叉编译环境(Ubuntu) | 在 Ubuntu 中搭建鸿蒙PC 三方库交叉编译构建开发环境 | 👉 点击查看 |
| 三方库交叉编译环境(macOS) | 在 macOS 中搭建鸿蒙PC 三方库交叉编译开发环境 | 👉 点击查看 |
| 基础环境搭建 | Windows 10 上安装和使用 WSL 2、安装 Ubuntu 24 详细指南 | 👉 点击查看 |
| Mac 移植指南 | 鸿蒙PC命令行适配指南(Mac 版) | 👉 点击查看 |
| Win 移植指南 | 鸿蒙PC 生态三方软件移植:开发环境搭建及三方库移植指南 | 👉 点击查看 |
| 全流程适配指南 | OpenHarmony Linux 命令行工具适配实战:基于 Cursor × WSL 的 tree 2.2.1 交叉编译与 HNP 打包全流程指南 | 👉 点击查看 |
| 官方构建文档 | 新脚手架:社区维护的鸿蒙PC 生态命令行工具构建框架 lycium_plusplus(原 build 仓库为旧方式,请以本仓库为准) | 👉 点击查看 |
2.1 lycium_plusplus 框架
lycium_plusplus 是本次适配工作的核心工具,主要用于统一管理各类第三方库的构建流程,通过规范编译、依赖与打包逻辑,实现三方库在目标平台上高效、稳定地编译与集成,是整个适配环节中保障构建一致性与可维护性的关键支撑。
# 克隆 lycium_plusplus 项目
git clone https://gitcode.com/OpenHarmonyPCDeveloper/lycium_plusplus.git
cd lycium_plusplus
2.2 CMake 与交叉编译环境
由于 G’MIC 是 C/C++ 项目,需要 CMake 和 OpenHarmony SDK 提供的交叉编译工具链。
# 安装 CMake
sudo apt-get install -y cmake
# 验证安装
cmake --version
# 配置 OpenHarmony SDK 环境变量
export OHOS_SDK=/home/weishuo/ohos-sdk/linux
三、实战:以 G’MIC 为例的适配步骤
3.1 创建项目目录结构
在 lycium_plusplus/thirdparty/ 目录下为 G’MIC 创建专属目录。
cd lycium_plusplus/thirdparty
mkdir -p gmic
cd gmic
3.2 创建 HPKBUILD 文件
HPKBUILD 作为 lycium 框架的核心构建脚本,完整定义了三方库的元信息配置及下载、编译、打包等全流程构建逻辑。
#!/bin/bash
pkgname=gmic
pkgver=3.5.0
pkgrel=0
pkgdesc="A full-featured open-source framework for digital image processing (CLI version)"
url="https://gmic.eu"
archs=("arm64-v8a")
license=("CeCILL-C")
depends=()
makedepends=("cmake")
autounpack=false
downloadpackage=false
buildtools="cmake"
srcpath="${LYCIUM_ROOT}/../Projects/${pkgname}"
builddir="${pkgname}-${pkgver}"
prepare() {
if [ -d "$srcpath" ]; then
echo "Using local source from: $srcpath"
mkdir -p "$builddir"
cp -rf "$srcpath"/* "$builddir/"
find "$builddir" -name "*.bak" -type f -delete 2>/dev/null || true
find "$builddir" -name "*:Zone.Identifier" -type f -delete 2>/dev/null || true
echo "Prepare completed in: $builddir"
else
echo "ERROR: Source not found at $srcpath"
exit 1
fi
}
build() {
cd "$builddir"
cmake "$@" \
-B"$ARCH-build" \
-S. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DBUILD_CLI=ON \
-DBUILD_LIB=OFF \
-DBUILD_LIB_STATIC=ON \
-DBUILD_MAN=OFF \
-DBUILD_BASH_COMPLETION=OFF \
-DENABLE_DYNAMIC_LINKING=OFF \
-DENABLE_LTO=OFF \
-DENABLE_OPENMP=OFF \
-DENABLE_ZLIB=ON \
-DZLIB_INCLUDE_DIR="${OHOS_SDK}/native/sysroot/usr/include" \
-DZLIB_LIBRARY="${OHOS_SDK}/native/sysroot/usr/lib/aarch64-linux-ohos/libz.so" \
> "$buildlog" 2>&1
ret=$?
if [ $ret -ne 0 ]; then
echo "CMake configuration failed!"
cat "$buildlog" >&2
cd "$OLDPWD"
return $ret
fi
cd "$ARCH-build"
$MAKE VERBOSE=1 >> "$buildlog" 2>&1
ret=$?
cd "$OLDPWD"
return $ret
}
check() {
echo "The test must be on an OpenHarmony device!"
}
package() {
: ${destdir:=${LYCIUM_ROOT}/usr/${pkgname}/${ARCH}}
mkdir -p "${destdir}/usr/bin"
_gmic_bin="${LYCIUM_ROOT}/../thirdparty/${pkgname}/${builddir}/${ARCH}-build/gmic"
if [ -f "$_gmic_bin" ]; then
cp -f "$_gmic_bin" "${destdir}/usr/bin/gmic"
chmod +x "${destdir}/usr/bin/gmic"
echo " ✅ Installed gmic binary"
else
echo " ❌ gmic binary not found at $_gmic_bin"
return 1
fi
mkdir -p "${destdir}/usr/share/gmic"
_gmic_stdlib="${LYCIUM_ROOT}/../thirdparty/${pkgname}/${builddir}/src/gmic_stdlib.gmic"
if [ -f "$_gmic_stdlib" ]; then
cp -f "$_gmic_stdlib" "${destdir}/usr/share/gmic/gmic_stdlib.gmic"
echo " ✅ Installed gmic_stdlib.gmic"
fi
find "${destdir}" -name "*.bak" -type f -delete 2>/dev/null || true
find "${destdir}" -name "*:Zone.Identifier" -type f -delete 2>/dev/null || true
return 0
}
archive() {
export HNP_TOOL="${HNP_TOOL:-${OHOS_SDK}/toolchains/hnpcli}"
mkdir -p ${LYCIUM_ROOT}/output/$ARCH
pushd ${LYCIUM_ROOT}/usr/${pkgname}/${ARCH} > /dev/null 2>&1
tar -zcf ${LYCIUM_ROOT}/output/$ARCH/${pkgname}_${pkgver}.tar.gz .
echo "Archive completed: ${LYCIUM_ROOT}/output/$ARCH/${pkgname}_${pkgver}.tar.gz"
popd > /dev/null 2>&1
if [ -f "${HNP_TOOL}" ]; then
cp ${LYCIUM_ROOT}/../thirdparty/${pkgname}/hnp.json ${LYCIUM_ROOT}/usr/${pkgname}/${ARCH}/
${HNP_TOOL} pack \
-i ${LYCIUM_ROOT}/usr/${pkgname}/${ARCH} \
-o ${LYCIUM_ROOT}/output/$ARCH/
echo "Archive completed: ${LYCIUM_ROOT}/output/$ARCH/${pkgname}.hnp"
else
echo "Warning: hnpcli not found at ${HNP_TOOL}, skipping HNP generation"
fi
}
cleanbuild() {
echo "Cleaning build artifacts for ${pkgname}..."
rm -rf "${LYCIUM_ROOT}/../thirdparty/${pkgname}/${builddir}"
rm -rf "${LYCIUM_ROOT}/output/${pkgname}"*
rm -rf "${LYCIUM_ROOT}/usr/${pkgname}"
echo "Clean completed"
}

3.3 创建 hnp.json(包元数据)
hnp.json 文件用于描述 HNP 包的元信息,类似于 package.json。
{
"type": "hnp-config",
"name": "gmic",
"version": "3.5.0",
"description": "A full-featured open-source framework for digital image processing (CLI version)",
"license": "CeCILL-C",
"arch": "arm64-v8a",
"install": {
"bin": ["usr/bin/gmic"],
"share": ["usr/share/gmic"]
}
}

3.4 创建 README.OpenSource(开源声明)
为了满足开源合规性,需要提供 README.OpenSource 文件来声明许可证和依赖库信息。
[
{
"Name": "gmic",
"License": "CeCILL-C",
"License File": "https://github.com/GreycLab/gmic/blob/master/COPYING",
"Version Number": "3.5.0",
"Owner": "your-email@example.com",
"Upstream URL": "https://github.com/GreycLab/gmic/archive/refs/tags/v3.5.0.tar.gz",
"Description": "G'MIC (GREYC's Magic for Image Computing) is a full-featured open-source framework for digital image processing."
},
{
"Name": "CImg",
"License": "CeCILL-C",
"License File": "https://github.com/dtschump/CImg/blob/master/LICENCE",
"Version Number": "3.4.0",
"Owner": "your-email@example.com",
"Upstream URL": "https://github.com/dtschump/CImg/archive/refs/tags/v.3.4.0.tar.gz",
"Description": "CImg Library is a C++ template toolkit for image processing."
},
{
"Name": "zlib",
"License": "Zlib",
"License File": "https://github.com/madler/zlib/blob/master/LICENSE",
"Version Number": "1.3.1",
"Owner": "your-email@example.com",
"Upstream URL": "https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz",
"Description": "zlib is a software library used for data compression."
}
]

3.5 创建 HPKCHECK 检查脚本
HPKCHECK 是 lycium 框架的构建检查脚本,用于在编译前验证环境是否满足构建要求。
#!/bin/bash
# HPKCHECK for G'MIC CLI
HPK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "${HPK_DIR}" || exit 1
source ./HPKBUILD > /dev/null 2>&1
logfile="${HPK_DIR}/${pkgname}_${ARCH}_test.log"
checkprepare() {
return 0
}
openharmonycheck() {
res=0
inst_bin="${LYCIUM_ROOT}/usr/${pkgname}/${ARCH}/usr/bin"
if [ -x "${inst_bin}/gmic" ]; then
cd "$inst_bin" || return 1
else
echo "no gmic binary in ${inst_bin}" >&2
return 1
fi
{
echo "start test times: $(date)"
echo "=== G'MIC CLI version check ==="
if [ -x ./gmic ]; then
./gmic --version
res=$(( res | $? ))
else
echo "missing ./gmic"
res=1
fi
echo "=== G'MIC CLI help check ==="
if [ -x ./gmic ]; then
./gmic --help 2>&1 | head -20
res=$(( res | $? ))
else
echo "missing ./gmic"
res=1
fi
echo "=== G'MIC CLI basic test ==="
if [ -x ./gmic ]; then
# 测试基本的图像处理命令(创建一个简单的图像)
./gmic sp 100,100 v 0 output /tmp/test_gmic.png 2>&1 | head -5
res=$(( res | $? ))
# 清理测试文件
rm -f /tmp/test_gmic.png
else
echo "missing ./gmic"
res=1
fi
echo "end test times: $(date)"
} >> "${logfile}" 2>&1
if [ $res -ne 0 ] && [ -n "${LYCIUM_FAULT_PATH}" ]; then
mkdir -p "${LYCIUM_FAULT_PATH}/${pkgname}"
fi
cd "${OLDPWD}"
return $res
}

四、编译流程与完整示例
4.1 环境准备
配置用于前置环境检查与变量设置,通过指定 OpenHarmony SDK 路径、验证 CMake 环境,为 lycium_plusplus 构建三方库提供基础运行环境。
# 1. 确保 OpenHarmony SDK 已安装
export OHOS_SDK=/home/weishuo/ohos-sdk/linux
# 2. 确保 CMake 已安装
cmake --version
4.2 创建项目结构并执行编译
通过目录操作、脚本创建、清理缓存、执行构建指令,完成 lycium_plusplus 中 G’MIC 三方库的从零构建全流程。
cd lycium_plusplus/thirdparty
mkdir -p gmic
cd gmic
# 创建 HPKBUILD 文件(内容见第三章)
vim HPKBUILD
cd ../../lycium
# 清理历史构建记录(可选,但推荐)
grep -v 'gmic' usr/hpk_build.csv > usr/hpk_build.csv.tmp
mv usr/hpk_build.csv.tmp usr/hpk_build.csv
rm -rf ../thirdparty/gmic/gmic-3.5.0
rm -rf output/*/gmic*
# 开始构建
./build.sh gmic
4.3 构建成功输出示例

4.4 验证产物
构建成功后,编译产物会统一输出至 output 目录,包含标准 tar 压缩包与鸿蒙专用 hnp 格式包。

五、鸿蒙PC 上验证结果(测试)


解压并进入目录,并且查看二进制文件并添加执行权限,执行签名操作。
# 解压到鸿蒙 PC 桌面(路径示例)
tar -zxf gmic_3.5.0.tar.gz
# 进入对应目录
cd /usr/bin
# 查看文件
ls -l
# 在鸿蒙 PC 上若策略要求,可对二进制签名(示例)
binary-sign-tool sign -inFile gmic -outFile gmic -selfSign "1"
# 按需添加执行权限
chmod +x gmic
# 执行测试(直接运行查看版本信息)
./gmic
G’MIC 命令测试,通过极简命令快速验证 G’MIC 在鸿蒙设备上的运行状态,依次检测程序启动、版本信息、图像生成与基础图像处理能力,无需图形界面即可快速判断移植适配是否成功。
# 查看当前 gmic 工具的版本信息
./gmic version
# 加载内置的 Lena 测试图像(标准图像处理测试图)
./gmic sp lena

六、常见问题与解决方案(FAQ)
Q1:构建时报错 “Missing gmic_stdlib_community.h”?
A:这是 CMake 的 FindGMicStdlib.cmake 强制要求的文件。需要从官网下载:
# 下载并保存
wget https://gmic.eu/gmic_stdlib_community375.h -O Projects/gmic/src/gmic_stdlib_community.h
# 或者从已有文件复制
cp gmic_stdlib_community375.h Projects/gmic/src/gmic_stdlib_community.h
Q2:真机运行时报错 “Error loading shared library libomp.so”?
A:这是因为启用了 OpenMP 但鸿蒙系统没有 libomp.so 运行时库。解决方案是在 HPKBUILD 中禁用 OpenMP:
# 在 HPKBUILD 的 cmake 命令中添加
-D ENABLE_OPENMP=OFF \
然后清理缓存并重新构建:
# 清理构建缓存
rm -f lycium/usr/hpk_build.csv
rm -rf thirdparty/gmic/gmic-*
rm -rf lycium/usr/gmic
# 重新构建
./lycium/build.sh gmic
Q3:真机运行时出现 “Could not decompress G’MIC standard library” 警告?
A:这是因为 zlib 未被正确链接。虽然设置了 ENABLE_ZLIB=ON,但 CMake 可能未找到 zlib 头文件。需要在 HPKBUILD 中显式指定 zlib 路径:
# 在 HPKBUILD 的 cmake 命令中添加
-D ENABLE_ZLIB=ON \
-D ZLIB_INCLUDE_DIR="${OHOS_SDK}/native/sysroot/usr/include" \
-D ZLIB_LIBRARY="${OHOS_SDK}/native/sysroot/usr/lib/aarch64-linux-ohos/libz.so" \
然后清理缓存并重新构建。
Q4:修改 HPKBUILD 后 lycium 直接跳过构建?
A:这是 lycium 的构建缓存机制导致的。lycium 使用 hpk_build.csv 文件记录构建状态,如果存在记录则会跳过构建。解决方案是删除缓存文件:
# 删除构建状态缓存
rm -f lycium/usr/hpk_build.csv
# 同时清理旧产物
rm -rf thirdparty/gmic/gmic-*
rm -rf lycium/usr/gmic
rm -rf lycium/output/*/*gmic*
# 重新构建
./lycium/build.sh gmic
Q5:为什么 ./gmic --help 和 ./gmic --version 报错?
A:G’MIC 不使用 -- 开头的标准命令行参数格式。正确的用法是:
# 查看帮助(使用 help 子命令)
./gmic help | less -r
# 查看版本信息(直接运行不带参数即可看到版本)
./gmic
输出中会显示版本信息:
gmic: GREYC's Magic for Image Computing: Command-Line Interface
Version 3.7.5
Q6:构建时报错 $‘\r’: command not found?
A:这是 Windows 换行符(CRLF)导致的问题。在 WSL + Windows 共享目录环境下,使用某些工具创建的文件会自动带有 CRLF 换行符。解决方案是使用 Python 脚本在 Linux 环境中转换:
# 使用 Python 二进制模式转换
python3 << 'EOF'
import os
files = [
"/home/weishuo/lycium_plusplus/thirdparty/gmic/HPKBUILD",
"/home/weishuo/lycium_plusplus/thirdparty/gmic/HPKCHECK"
]
for filepath in files:
with open(filepath, "rb") as f:
content = f.read()
content = content.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
with open(filepath, "wb") as f:
f.write(content)
print(f"Fixed: {filepath}")
print("All files fixed!")
EOF
Q7:如何验证 gmic 是否正确使用了 zlib?
A:运行 gmic 时如果不出现 “Could not decompress” 警告,说明 zlib 已正确链接。也可以使用 ldd 命令检查(在构建环境中):
# 检查动态链接库
ldd thirdparty/gmic/gmic-3.5.0/arm64-v8a-build/gmic
# 应该能看到 libz.so 在链接列表中
在真机上,直接运行 ./gmic 并观察输出即可。
Q8:gmic_stdlib.gmic 文件的作用是什么?必须包含吗?
A:gmic_stdlib.gmic 是 G’MIC 的标准库文件,包含 1000+ 滤镜命令的定义。虽然 gmic 可以运行,但如果没有这个文件:
- 无法使用标准库中的高级滤镜命令
- 会显示 “Could not decompress” 警告(如果 zlib 也未正确配置)
七、技术总结
本次成功将 G’MIC CLI 适配至 OpenHarmony 平台,形成了一套可复用的 C/C++ 库鸿蒙移植范式。核心要点如下:
- 标准化适配模板:建立了 CMake 类项目的 HPKBUILD 配置规范,统一交叉编译与依赖管理流程
- 关键问题解决:通过禁用 OpenMP 规避运行时依赖、显式配置 zlib 路径确保标准库解压、正确管理 CImg 大型头文件
- 轻量化部署:精简打包产物,显著降低部署体积,提升鸿蒙设备上的分发效率
- 通用适配能力:方案可直接迁移至 ImageMagick、GraphicsMagick、FFmpeg 等同类图像/多媒体处理工具的鸿蒙移植
八、结语
本次实践成功将 G’MIC CLI 移植至 鸿蒙PC 平台,验证了 lycium_plusplus 框架对 C/C++ 项目交叉编译的支撑能力。通过规范 HPKBUILD 构建流程、禁用 OpenMP 规避运行时依赖、显式配置 zlib 路径、精简产物体积等关键措施,有效解决了适配中的兼容性与构建问题,为同类开源项目迁移至鸿蒙生态提供了可复用的实践参考,助力鸿蒙原生工具生态的完善与发展。
提示:本文基于 G’MIC 3.5.0 版本进行适配。不同版本的依赖和构建脚本可能有所差异,建议在适配前先熟悉目标项目的 CMakeLists.txt 和构建配置文件。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)