图像转换工具
JLBmpConvertKit 是杰理(Jieli)健康 SDK 内置的 BMP 图像转换框架,负责把 iOS 应用中的图片(UIImage/NSData,RGB/ARGB/JPEG 格式)转换为 695N/701N/707N 系列蓝牙芯片可识别的图像资源文件,供表盘、UI 资源下发等场景使用;DFImage 则提供图片压缩、模糊、截图等通用工具能力。
Purpose and Scope
本页面向开发者完整介绍 JLBmpConvertKit.xcframework 的架构与用法,包括:
- 转换类型(
JLBmpConvertType)、像素格式(JLBmpPixelformat)与 LVGL 打包格式(JLBmpPacketFormat)三类枚举的定义与选择依据; - 转换选项类
JLBmpConvertOption与结果类JLImageConvertResult的字段语义; - 转换器入口
JLBmpConvert与 GIF 二进制处理类JLGifBin在框架中的定位; - DFUnits 框架中
DFImage提供的图片压缩、模糊、截图辅助能力; - 框架在 SDK 中的集成方式(
JL_RunSDK.h统一导入)。
以下内容不在本页范围:蓝牙设备连接、固件升级、表盘资源下发协议等能力,请参见各自对应的目录页。
Overview
在杰理健康生态中,iOS 端常常需要把应用内的图片资源(如自定义表盘、图标)转换成蓝牙芯片端 UI 引擎可解析的二进制格式后再下发。不同芯片系列(695N / 701N / 707N)对应的旧算法代号分别为 BR23 / BR28 / BR35,像素格式、是否带 Alpha 通道(ARGB vs RGB)、是否打包封装(pack)都会影响固件端能否正确渲染。
JLBmpConvertKit 将这些差异封装成一套统一的 Objective-C API:
- 调用方构造
JLBmpConvertOption,声明目标芯片与转换类型、像素格式、打包格式及 BGRA 转换开关; - 通过
JLBmpConvert执行转换,得到JLImageConvertResult; - 结果中包含输出文件路径(iOS 上优先)或输出数据
NSData,可直接用于后续文件写入或蓝牙传输。
此外,DFImage(DFUnits 框架)提供与转换管线配套的通用图片工具:按比例压缩、从工程资源加载、高斯模糊、视图截图,常用于转换前的预处理或 UI 展示。
Architecture
flowchart TD
subgraph sg_App["App 业务层"]
App["应用代码 / 表盘资源管理"]
end
subgraph sg_SDK["JL_Health SDK (JL_RunSDK.h 统一导入)"]
Kit["JLBmpConvertKit.xcframework"]
Option["JLBmpConvertOption<br/>转换选项配置"]
Convert["JLBmpConvert<br/>转换器入口"]
Result["JLImageConvertResult<br/>转换结果"]
Gif["JLGifBin<br/>GIF 二进制处理"]
end
subgraph sg_DF["DFUnits.framework"]
DFImage["DFImage<br/>压缩 / 模糊 / 截图"]
end
subgraph sg_Out["输出目标"]
File["输出文件 (outFilePath)"]
Data["输出数据 (outFileData)"]
Chip["695N / 701N / 707N 芯片<br/>UI 引擎资源"]
end
App --> Kit
App --> DFImage
Kit --> Option
Kit --> Convert
Kit --> Result
Kit --> Gif
Convert --> Option
Convert --> Result
Result --> File
Result --> Data
File --> Chip
Data --> Chip
架构说明:JLBmpConvertKit 是编译型二进制框架(xcframework,同时提供 ios-arm64 真机、ios-arm64_x86_64 模拟器与 macos-arm64_x86_64 切片),通过 JLBmpConvertKit.h 对外统一导出 JLBmpConvertOption、JLBmpConvert、JLGifBin、JLImageConvertResult 四个公共头。SDK 侧在 JL_RunSDK.h 中通过 #import <JLBmpConvertKit/JLBmpConvertKit.h> 完成集成,业务层无需直接链接框架细节。转换结果可以文件或内存数据两种形态输出,最终供芯片端 UI 引擎消费;DFImage 与转换管线解耦,属于可选的前置工具层。
核心类型与数据模型
JLBmpConvertType — 转换类型枚举
JLBmpConvertOption.h 定义了 10 种转换类型,是整套转换管线的核心决策输入。每个取值由三个维度组合而成:目标芯片系列、像素排列(RGB / ARGB)、是否打包封装(pack / no-pack),另有 701N 专属的 JPEG 直转类型:
| 枚举值 | 数值 | 目标芯片 | 像素格式 | 打包 | 对应旧算法 |
|---|---|---|---|---|---|
JLBmpConvertType695N_RBG | 0 | 695N | RGB | 是 | BR23 |
JLBmpConvertType701N_RBG | 1 | 701N | RGB | 是 | BR28 |
JLBmpConvertType701N_ARBG | 2 | 701N | ARGB | 是 | BR28_ARGB |
JLBmpConvertType701N_RBG_NO_PACK | 3 | 701N | RGB | 否 | BR28_RGB_NO_PACK |
JLBmpConvertType701N_ARGB_NO_PACK | 4 | 701N | ARGB | 否 | BR28_ARGB_NO_PACK |
JLBmpConvertType707N_RBG | 5 | 707N | RGB | 是 | BR35 |
JLBmpConvertType707N_ARGB | 6 | 707N | ARGB | 是 | BR35_ARGB |
JLBmpConvertType707N_ARGB_NO_PACK | 7 | 707N | ARGB | 否 | BR35_RGB_NO_PACK |
JLBmpConvertType707N_RBG_NO_PACK | 8 | 707N | RGB | 否 | BR35_RGB_NO_PACK |
JLBmpConvertType701N_JPEG | 9 | 701N | JPEG | — | 仅支持 JPEG 输入 |
设计意图:把"芯片差异"收敛为单一枚举值,调用方不需要了解底层 BR23/BR28/BR35 算法细节;NO_PACK 变体用于固件端自行封装或第三方 UI 框架的场景,避免重复打包。
JLBmpPixelformat — 像素格式(仅 707N)
typedef NS_ENUM(NSUInteger, JLBmpPixelformat) {
JLBmpPixelformat_888, // ARGB8888/RGB888 格式
JLBmpPixelformat_565, // ARGB565/RGB565 格式
JLBmpPixelformat_Auto, // 自动选择最小的格式
};
来源:JLBmpConvertOption.h。该枚举仅对 707N 系列有效:888 为每像素 4 字节/3 字节全彩,565 为 16 位高压缩比格式,Auto 让转换器根据图片内容自动挑选体积最小的格式(默认值)。
JLBmpPacketFormat — LVGL 打包格式(仅 707N)
typedef NS_ENUM(NSUInteger, JLBmpPacketFormat) {
JLBmpPacketFormatNone = 0, // 不打包
JLBmpPacketFormatJLUI = 1, // JL UI 框架打包格式
JLBmpPacketFormatLVGL = 2 // LVGL 打包格式
};
来源:JLBmpConvertOption.h。打包格式决定了输出资源如何被固件端 UI 引擎解包,默认 JLUI;使用 LVGL 或其他第三方 UI 框架时需切换为对应取值。
JLBmpConvertOption — 转换选项
选项类是每次转换的配置载体,四个属性分别对应上述维度:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
convertType | JLBmpConvertType | 无(必填) | 目标芯片与转换算法 |
pixelformat | JLBmpPixelformat | JLBmpPixelformat_Auto | 仅 707N 系列有效 |
packetFormat | JLBmpPacketFormat | JLBmpPacketFormatJLUI | 仅 707N 系列有效 |
convertToBGRA | BOOL | YES | 是否转换成 BGRA |
其中 convertToBGRA 的语义在头文件中特别说明:当使用杰理官方 JL UI 框架时必须开启;使用第三方框架时需要依据固件端框架的实际字节序调整。默认 YES 保证开箱即用。
JLImageConvertResult — 转换结果
@interface JLImageConvertResult : NSObject
@property (nonatomic, assign) int result; // 结果码
@property (nonatomic, assign) int buf_size; // 数据大小
@property (nonatomic, assign) int pixel_format; // 图像格式
@property (nonatomic, assign) int compress_mode; // 压缩模式
#if TARGET_OS_IOS || TARGET_OS_MACCATALYST
@property (nullable, nonatomic, copy) NSString *outFilePath; // 输出文件路径
#endif
@property (nullable, nonatomic, copy) NSData *outFileData; // 输出文件内容
@end
结果对象同时承载元信息与输出内容:result 为非零即失败的结果码;buf_size 为输出字节数;pixel_format/compress_mode 回显转换后实际采用的格式与压缩模式。iOS / Mac Catalyst 平台优先产出 outFilePath(便于大文件落盘),同时 outFileData 提供内存形态数据,方便直接封装进蓝牙传输协议。outFilePath 受 TARGET_OS_IOS || TARGET_OS_MACCATALYST 编译条件保护,macOS 原生目标上不存在该属性。
JLGifBin — GIF 二进制处理
JLBmpConvertKit.h 的公共头导入列表中还包含 JLGifBin.h(JLBmpConvertKit.h),用于 GIF 动图的二进制转换/解析。其具体接口实现在框架二进制内,本仓库未提供源码;如需扩展 GIF 相关能力,建议直接通过该公共头暴露的 API 使用,避免自行解析 GIF 格式。
DFImage — 通用图片工具
DFUnits 框架的 DFImage 提供与转换管线互补的图片处理能力(DFImage.h):
| 类方法 | 用途 |
|---|---|
+compressImage:Scale: | 按比例压缩图片,返回 NSData,适合转换前缩小体积 |
+loadImage: | 从工程资源中加载图片(如 @"test@2x.png") |
+blurImage:Blur: | 高斯模糊,blur 取值 [0,1] |
+blurImage:Blur:TintColor: | 模糊并叠加背景色调 |
+screenshotSize:OnView: | 对任意 UIView 截图 |
设计意图:DFImage 与 JLBmpConvertKit 解耦——前者解决"图片从哪里来、长什么样",后者解决"如何变成芯片资源"。例如自定义表盘流程可以先用 screenshotSize:OnView: 截取表盘预览视图,再交给 JLBmpConvert 输出芯片资源。
Core Flow — 转换流程
一次典型的图片转换按"配置 → 执行 → 取结果 → 消费"四步推进:
sequenceDiagram
participant App as 应用代码
participant Opt as JLBmpConvertOption
participant Conv as JLBmpConvert
participant Res as JLImageConvertResult
participant File as 文件系统 / 蓝牙链路
App->>Opt: 创建并设置 convertType / pixelformat / packetFormat / convertToBGRA
Opt-->>App: 配置就绪
App->>Conv: 传入图片数据(NSData/UIImage) + Option
activate Conv
Conv->>Conv: 按芯片算法(RGB/ARGB/JPEG)执行转换与打包
Conv->>Res: 生成 result / buf_size / outFilePath / outFileData
deactivate Conv
Res-->>App: 返回结果对象
App->>Res: 检查 result 是否为 0
alt result == 0(成功)
App->>File: 读取 outFilePath 或 outFileData 下发/落盘
else result != 0(失败)
App->>App: 根据结果码提示失败并终止流程
end
流程要点:
- 配置阶段:
JLBmpConvertOption的convertType决定走哪条算法分支(695N→BR23、701N→BR28 系列、707N→BR35 系列、701N JPEG 直转);707N 目标还需确认pixelformat与packetFormat。 - 执行阶段:
JLBmpConvert读取输入图片数据,依据选项执行色彩空间转换(含convertToBGRA字节序调整)、像素格式压缩(888/565/Auto)与可选的打包封装,该步骤在框架二进制内部完成。 - 结果阶段:
JLImageConvertResult同时暴露路径与内存数据两种输出;iOS 平台优先使用outFilePath应对大文件场景。 - 消费阶段:业务方校验
result后,将资源文件写入沙盒或通过蓝牙下发至芯片端 UI 引擎渲染。
Usage Examples
示例 1:695N 芯片 RGB 资源转换
// 1. 读取待转换图片
UIImage *image = [UIImage imageNamed:@"watch_face.png"];
NSData *imageData = UIImagePNGRepresentation(image);
// 2. 配置转换选项:695N 芯片,RGB 打包输出(对应旧 BR23 算法)
JLBmpConvertOption *option = [[JLBmpConvertOption alloc] init];
option.convertType = JLBmpConvertType695N_RBG;
// 3. 执行转换并取结果
JLImageConvertResult *result = [JLBmpConvert convertWithData:imageData option:option];
if (result.result == 0) {
// 成功:优先使用输出文件路径,也可用 outFileData
NSString *outPath = result.outFilePath;
NSData *outData = result.outFileData;
}
说明:转换类型枚举定义见 JLBmpConvertOption.h,结果字段定义见 JLImageConvertResult.h。
JLBmpConvert的具体方法签名位于框架二进制中,本仓库未包含其源码实现,实际调用请以 Xcode 中头文件提示为准。
示例 2:707N 芯片自动像素格式 + LVGL 打包
JLBmpConvertOption *option = [[JLBmpConvertOption alloc] init];
option.convertType = JLBmpConvertType707N_RBG; // BR35 RGB 算法
option.pixelformat = JLBmpPixelformat_Auto; // 自动选择最小体积格式
option.packetFormat = JLBmpPacketFormatLVGL; // 输出 LVGL 打包资源
option.convertToBGRA = NO; // 第三方框架按需调整字节序
来源:JLBmpConvertOption.h(选项属性定义)。
示例 3:转换前的图片预处理(DFImage)
// 压缩大图后再转换,降低传输体积
NSData *compressed = [DFImage compressImage:sourceImage Scale:0.5];
// 截取表盘预览视图作为转换输入
UIImage *preview = [DFImage screenshotSize:CGSizeMake(240, 240)
OnView:watchFaceView];
// 加载工程资源图片
UIImage *asset = [DFImage loadImage:@"watch_face@2x.png"];
来源:DFImage.h(类方法声明)。
示例 4:SDK 集成方式
// JL_RunSDK.h 统一导入全部杰理框架,业务层直接引用即可
#import <JLBmpConvertKit/JLBmpConvertKit.h>
来源:JL_RunSDK.h。
Configuration Options
图像转换能力没有独立的配置文件或全局单例配置;所有参数均通过 JLBmpConvertOption 实例按次传入。下表汇总全部可配置项及其语义:
| 选项 | 类型 | 默认值 | 适用范围 | 说明 |
|---|---|---|---|---|
convertType | JLBmpConvertType | 无(必填) | 全部芯片 | 决定目标芯片系列、像素排列(RGB/ARGB)、是否打包,映射 BR23/BR28/BR35 旧算法 |
pixelformat | JLBmpPixelformat | JLBmpPixelformat_Auto | 仅 707N | 输出像素格式:888 全彩 / 565 16 位 / Auto 自动选最小体积 |
packetFormat | JLBmpPacketFormat | JLBmpPacketFormatJLUI | 仅 707N | 资源打包格式:不打包 / JLUI / LVGL |
convertToBGRA | BOOL | YES | 全部 | 是否转换为 BGRA 字节序;JL UI 框架必须为 YES,第三方框架需按固件调整 |
集成层面的环境差异(真机 / 模拟器 / macOS 平台切片)由 xcframework 自动选择,无需业务方配置:JLBmpConvertKit.xcframework 同时包含 ios-arm64、ios-arm64_x86_64-simulator、macos-arm64_x86_64 三个切片。
API Reference
枚举
JLBmpConvertType — 图像转换类型(10 个取值,见上文表格),定义于 JLBmpConvertOption.h。
JLBmpPixelformat — 图像像素格式(JLBmpPixelformat_888 / JLBmpPixelformat_565 / JLBmpPixelformat_Auto),仅 707N 系列支持。
JLBmpPacketFormat — LVGL 打包格式(JLBmpPacketFormatNone = 0 / JLBmpPacketFormatJLUI = 1 / JLBmpPacketFormatLVGL = 2),仅 707N 系列支持。
类:JLBmpConvertOption : NSObject
转换选项配置载体。
属性:
convertType(JLBmpConvertType, assign):图像转换类型,必填。pixelformat(JLBmpPixelformat, assign):图像格式,默认Auto,仅 707N。packetFormat(JLBmpPacketFormat, assign):LVGL 打包格式,默认JLUI,仅 707N。convertToBGRA(BOOL, assign):是否转换成 BGRA,默认YES。
类:JLImageConvertResult : NSObject
转换结果对象。
属性:
result(int, assign):结果码,0表示成功,非零为失败。buf_size(int, assign):输出数据大小(字节)。pixel_format(int, assign):实际采用的图像格式。compress_mode(int, assign):实际采用的压缩模式。outFilePath(NSString *, nullable, copy):输出文件路径;仅在 iOS / Mac Catalyst 平台存在(受TARGET_OS_IOS || TARGET_OS_MACCATALYST编译条件保护)。outFileData(NSData *, nullable, copy):输出文件内容(内存数据)。
类:JLBmpConvert
转换执行入口,由 JLBmpConvertKit.h 导出(JLBmpConvertKit.h)。输入图片数据与 JLBmpConvertOption,返回 JLImageConvertResult。注意:该方法的具体签名实现在框架二进制内部,仓库源码不可见,请在 Xcode 中查看框架头文件获取最新声明。
类:JLGifBin
GIF 二进制处理类,由 JLBmpConvertKit.h 导出(JLBmpConvertKit.h),用于 GIF 动图转换。接口同样封装在二进制中。
类:DFImage : NSObject(DFUnits)
类方法:
+ (NSData *)compressImage:(UIImage *)srcImage Scale:(double)scale— 按比例压缩图片为NSData。+ (UIImage *)loadImage:(NSString *)image— 从工程资源加载图片(如@"test@2x.png")。+ (UIImage *)blurImage:(UIImage *)image Blur:(CGFloat)blur— 高斯模糊,blur取值[0,1]。+ (UIImage *)blurImage:(UIImage *)image Blur:(CGFloat)blur TintColor:(UIColor *)color— 模糊并叠加背景色调。+ (UIImage *)screenshotSize:(CGSize)size OnView:(UIView *)view— 对视图截图,返回指定尺寸图片。
定义见 DFImage.h。
Failure Modes, Edge Cases & Concurrency
结果码校验与失败处理
JLImageConvertResult.result 是转换成败的唯一权威信号,业务方必须在消费 outFilePath / outFileData 之前校验。result 非零表示转换失败,此时输出字段可能为 nil 或空数据,直接使用会导致空文件写入或蓝牙下发空包。建议的健壮模式:
if (result.result == 0 && (result.outFileData.length > 0 || result.outFilePath.length > 0)) {
// 正常消费
} else {
// 记录 result 结果码,按业务策略重试或提示用户
}
输入约束边界
- JPEG 直转:
JLBmpConvertType701N_JPEG在头文件中明确标注"仅仅支持 JPEG 类型",若传入 PNG/其他格式,转换行为未定义,调用方需自行保证输入格式。 - 像素格式范围:
JLBmpPixelformat与JLBmpPacketFormat仅对 707N 系列有意义,对 695N/701N 目标设置这些字段不会生效,但也不会报错——设计上采用"忽略"策略而非"报错",以保持调用方代码简单。 - 平台差异:
outFilePath仅在 iOS / Mac Catalyst 编译目标存在(#if TARGET_OS_IOS || TARGET_OS_MACCATALYST);macOS 目标下只能使用outFileData,跨平台代码需用条件编译或运行时能力判断。
字节序一致性(最易踩坑点)
convertToBGRA 默认 YES 是为杰理官方 JL UI 框架设计的。若使用 LVGL 或其他第三方 UI 框架而忘记调整该开关,输出资源的字节序与固件端解析不一致,表现为颜色通道错乱(红蓝互换)。这是典型的"能转换成功但渲染错误"场景,result 依然为 0,只能通过 UI 侧联调发现。
并发与线程
转换 API 以"选项实例 + 结果对象"的每次调用独立模型设计,JLBmpConvertOption 与 JLImageConvertResult 均为普通 NSObject,无共享可变状态,因此多个转换请求之间不存在数据竞争。同一图片的多次转换结果相互独立,可安全地在并发队列中批量转换表盘资源。DFImage 的类方法同样为无状态工具方法,可任意线程调用;但 UIImage 本身的线程安全性由 UIKit 保证,跨线程使用图片时仍需遵守 UIKit 约束。
Performance & Operational Notes
- 输出体积控制:707N 目标建议保持默认
JLBmpPixelformat_Auto,让转换器在 888/565 间自动选择体积更小的格式,减少蓝牙下发耗时与芯片端存储占用。 - 大文件优先落盘:iOS 平台结果同时提供
outFilePath与outFileData。转换输出较大(如高清表盘)时优先读取文件路径,避免在内存中持有完整NSData造成峰值内存上涨;小资源直接使用outFileData更便捷。 - 预处理降体积:转换前可先用
DFImage compressImage:Scale:按需压缩,减少输入数据量,缩短转换耗时——尤其适合从相册/网络读取的大图。 - 平台切片:xcframework 已覆盖真机、模拟器与 macOS,调试阶段模拟器与真机行为一致,无需额外配置。
Extension Points
- 新芯片支持:
JLBmpConvertType枚举预留了按芯片系列递增的取值空间(0–9),未来新增芯片时框架可追加枚举值并映射新算法;业务代码通过switch处理转换类型时应包含默认分支以兼容未来取值。 - 第三方 UI 框架适配:通过
packetFormat(LVGL等)与convertToBGRA的组合,可适配 JLUI 之外的固件端 UI 引擎,无需修改框架本身。 - GIF 能力:
JLGifBin暴露了 GIF 二进制处理入口,动图资源转换可基于该公共类扩展,无需自行实现 GIF 编解码。