TGFX - 腾讯开源的轻量级 2D 渲染引擎

TGFX - 腾讯开源的轻量级 2D 渲染引擎

  • 首页
  • 下载
  • 文档
  • 案例
  • CN
  • GitHub
  • 论坛交流
  • Languages iconEN
    • CN

›图像与像素

快速开始

  • TGFX 简介
  • 平台与后端支持
  • 环境准备与编译
  • Hello2D 示例

API 参考与概述

    绘图基础

    • Canvas Overview
    • Paint Overview
    • Path Overview
    • BlendMode Overview
    • Picture 录制与回放

    几何与变换

    • 几何与变换

    图像与像素

    • Image
    • Bitmap 与像素操作
    • 图像编解码
    • 视频与外部纹理

    文本渲染

    • 文本与字体

    着色与效果

    • 着色与效果

    图层系统

    • 图层系统

    进阶主题

    • 自定义 Shader
    • 色彩管理

架构设计

  • 渲染管线
  • GPU 硬件抽象层
  • 图层渲染系统
  • 缓存系统
  • 文字图集渲染
  • GPU Hairline 极细描边
  • 广色域渲染
  • SIMD 加速

API 文档

  • API 文档

图像编解码

ImageCodec 是 TGFX 对静态图像格式(PNG/JPEG/WebP/HEIF)的统一解码与编码调度中心。

在多平台环境中,屏蔽底层编解码 API(如 Android BitmapFactory 与 iOS ImageIO)的差异是核心诉求。通过仅在头部解析时获取元数据,避免了不必要的内存分配;同时允许在解码瞬间进行尺寸调整,确保在低内存设备上也能处理大幅照片。


1. ImageCodec 统一接口

ImageCodec 隐藏了不同图片格式间的解析差异,提供了跨平台一致的操作体验。

1.1 支持的格式与识别

TGFX 能够自动识别文件头标识(Magic Numbers),无需手动指定格式。

  • 内置格式:PNG, JPEG, WebP。
  • 平台特有:如 iOS 的 HEIF / HEIC。

代码示例:检查解码器创建

// 传入任意支持路径,内部自动判断格式
auto codec = ImageCodec::MakeFrom("test.heic");
if (codec) {
    printf("Format identified, Size: %d x %d\n", codec->width(), codec->height());
}

1.2 协作流程

MakeFrom (属性识别) → orientation (旋转校正) → readPixels (下采样解码) → Bitmap (像素结果)


2. 解码:MakeFrom 与 readPixels

解码过程分为“元数据探测”和“像素生成”两个阶段,旨在实现极致的内存保护。

2.1 探测元数据 (MakeFrom)

MakeFrom 仅执行头文件解析,不分配庞大的像素数组。

代码示例:轻量探测

auto data = Data::MakeWithCopy(buffer, size);
auto codec = ImageCodec::MakeFrom(data); // 瞬间完成,无像素计算开销
auto colorSpace = codec->colorSpace();    // 获取图片的色彩空间属性

2.2 执行解码与下采样 (readPixels)

支持在读取字节流的同时进行 Box-filter 下采样。

代码示例:下采样解码 (4K 转缩略图)

// 1. 创建属性识别器
auto codec = ImageCodec::MakeFrom("4k_photo.jpg");

// 2. 目标:解码为原图 1/10 尺寸的位图
auto dstInfo = ImageInfo::Make(codec->width() / 10, codec->height() / 10, ColorType::RGBA_8888);
Bitmap bitmap;
bitmap.allocPixels(dstInfo.width(), dstInfo.height());

// 3. 执行下采样解码(内存峰值极低)
bool success = codec->readPixels(dstInfo, bitmap.lockPixels());
bitmap.unlockPixels();

2.3 Orientation 自动处理

ImageCodec 负责解析元数据,而高层 API 负责应用它。

代码示例:处理带旋转信息的图像

auto codec = ImageCodec::MakeFrom("portrait.jpg");
if (codec->orientation() != Orientation::TopLeft) {
    // 解码出的像素已经是根据 orientation() 物理校正后的
    // 无需手动对 Canvas 应用 Rotate 矩阵
}

3. 编码:导出与序列化

TGFX 提供两种编码方式,将内存中的像素数据持久化为压缩文件字节流:

  • Bitmap::encode(format, quality)(实例方法):直接对 Bitmap 内容编码,返回 Data 对象。默认格式为 PNG,质量 100。
  • ImageCodec::Encode(pixmap, format, quality)(静态方法):接受 Pixmap 视图进行编码,适合在不持有 Bitmap 的场景下使用。

注意:Pixmap 本身没有 encode() 方法。如需编码 Pixmap 的像素数据,请使用静态方法 ImageCodec::Encode(pixmap, format, quality)。

3.1 编码接口与参数

导出操作支持指定格式和压缩质量。支持的 EncodedFormat 包括 JPEG、PNG、WEBP 三种。

注意:导出为 JPEG 时,原本透明的区域会被填充为纯黑色。

代码示例:保存截图为 WebP

// 1. 获取包含像素的 Bitmap
Bitmap screenshot = ...; 

// 2. 编码为 WebP 格式,质量设为 85
auto webpData = screenshot.encode(EncodedFormat::WEBP, 85);

// 3. 写入文件系统
if (webpData) {
    FILE* file = fopen("out.webp", "wb");
    fwrite(webpData->data(), 1, webpData->size(), file);
    fclose(file);
}

4. 各平台差异说明

4.1 编码格式支持汇总

TGFX 可以编码的格式受到 EncodedFormat 枚举限制,仅支持 PNG、JPEG、WebP 三种。但解码支持的格式则因平台而异。

4.2 各平台详细对比

跨平台内置编解码器(始终可用)

格式解码编码库备注
PNG✅✅libpng无损格式,编码质量参数无效
JPEG✅✅libjpeg-turbo有损格式,支持质量参数 (0-100)
WebP✅✅libwebp支持有损/无损,质量参数 (0-100)

Apple (iOS/macOS) - ImageIO 框架

格式解码编码特性最低版本
PNG✅❌使用内置编解码器—
JPEG✅❌使用内置编解码器—
WebP✅❌iOS 14+ / macOS 11+iOS 14 / macOS 11
HEIF✅✅硬件加速(推荐)iOS 11 / macOS 10.13
HEIC✅✅HEIF 容器 + H.265 编码iOS 11 / macOS 10.13
GIF✅❌静态帧提取—
BMP✅❌——
TIFF✅❌多页面支持—
ICO✅❌图标格式—

推荐场景:iOS 项目首选 HEIF/HEIC,性能最佳。

Android - BitmapFactory

格式解码编码特性最低版本
PNG✅❌——
JPEG✅❌硬件编解码—
WebP✅❌静态和动画API 14+
GIF✅❌静态帧提取—
BMP✅❌——
HEIF✅❌MediaCodec 支持Android 9+
HEIC✅❌设备相关Android 9+

限制:Android 端不支持编码,需用平台 API 单独处理。编码请用 Java 侧的 Bitmap 方案。

Windows - Windows Imaging Component (WIC)

格式解码编码特性最低版本
PNG✅❌使用内置编解码器—
JPEG✅❌使用内置编解码器—
BMP✅❌——
GIF✅❌静态帧—
TIFF✅❌全页面支持—
ICO✅❌——
WebP✅❌—Windows 10 Build 1903+
HEIF✅❌—Windows 10 Build 1903+
HEIC✅❌—Windows 10 Build 1903+

特点:格式支持最丰富的平台,自动提取 EXIF/XMP 方向元数据。

OpenHarmony (OHOS) - ImageSourceNative NAPI

格式解码编码备注
PNG✅❌—
JPEG✅❌—
GIF✅❌—
WebP✅❌—
BMP✅❌—
HEIC✅❌设备相关

Web (Emscripten/浏览器)

格式解码编码浏览器支持
PNG✅❌所有浏览器
JPEG✅❌所有浏览器
GIF✅❌所有浏览器
WebP✅❌Chrome 23+, Firefox 65+, Safari 16+
AVIF✅❌Chrome 85+, Firefox 93+
TIFF✅❌部分浏览器

依赖:浏览器原生支持,无额外库。

Linux 与其他平台

平台PNGJPEGWebP其他
Linux✅✅✅❌
其他 POSIX✅✅✅❌

限制:仅支持内置三种格式,无平台原生编解码器支持。

4.3 格式自动识别机制

ImageCodec::MakeFrom() 会按以下优先级自动识别格式:

  1. 文件头特征识别(如果启用了内置编解码器):

    • WebP:RIFF 头 + "WEBP" 标签 @ offset 8
    • PNG:8 字节签名 89 50 4E 47 0D 0A 1A 0A
    • JPEG:3 字节 SOI 标记 FF D8 FF
  2. 平台原生解码器:

    • Apple:CGImageSource(自动识别 HEIF/HEIC/BMP/GIF/TIFF 等)
    • Android:BitmapFactory(自动识别平台支持的所有格式)
    • Windows:WIC(自动识别 BMP/GIF/TIFF/ICO/HEIF/WebP 等)
    • 其他平台:按此顺序尝试
  3. 失败返回 nullptr:若无编解码器支持该格式

无需手动指定格式,TGFX 会自动识别。

4.4 EXIF 方向元数据处理

所有平台的 ImageCodec 都会自动提取并应用图像方向信息:

  • 标准来源:JPEG 的 EXIF Orientation 标签、TIFF IFD、HEIF/PNG 的方向字段
  • 自动校正:通过 orientation() 属性获取,Image::makeOriented() 应用变换
  • 无需手动处理:方向校正已在解码层完成

4.5 编码质量参数对比

// 在 ImageCodec::Encode(pixmap, format, quality) 中:
// quality 参数含义因格式而异

// PNG: 质量参数无效(总是无损,但压缩级别内部固定)
auto png = ImageCodec::Encode(pixmap, EncodedFormat::PNG, 100);  // 参数被忽略

// JPEG: 质量 0-100 映射到 libjpeg-turbo 质量
//       推荐 85-95 获得最佳视觉质量
auto jpg = ImageCodec::Encode(pixmap, EncodedFormat::JPEG, 85);

// WebP: 质量 0-100(有损模式)
//       75+ 可保证高保真度
auto webp = ImageCodec::Encode(pixmap, EncodedFormat::WEBP, 80);

4.6 选择编码格式的建议

场景推荐格式原因
最大兼容性PNG所有平台/浏览器支持
文件大小优先WebP体积最小(需 Chrome/现代浏览器)
iOS 高性能HEIF/HEIC硬件编码,体积小,质量优
透明度 + 兼容PNGPNG 支持透明,JPEG 会变黑
Web 前端优化WebP + PNG 降级WebP 优先,不支持时用 PNG
实时/流媒体JPEG最快编码速度

5. 代码实战:编码格式对比

以下示例展示了同一张图像经过不同格式和质量编码后的效果与文件大小差异:

// 1. Prepare source pixels from a Bitmap
Bitmap sourceBitmap(200, 200);
// ... fill bitmap with image data ...

// 2. Encode to different formats
auto pngData = sourceBitmap.encode(EncodedFormat::PNG, 100);      // Lossless
auto jpegHigh = sourceBitmap.encode(EncodedFormat::JPEG, 90);     // High quality
auto jpegLow = sourceBitmap.encode(EncodedFormat::JPEG, 10);      // Low quality
auto webpData = sourceBitmap.encode(EncodedFormat::WEBP, 80);     // Balanced

// 3. Decode back from encoded data
auto pngImage = Image::MakeFromEncoded(pngData);
auto jpegHighImage = Image::MakeFromEncoded(jpegHigh);
auto jpegLowImage = Image::MakeFromEncoded(jpegLow);
auto webpImage = Image::MakeFromEncoded(webpData);

// 4. Draw each image for visual comparison
canvas->drawImage(pngImage, 0, 0);        // Identical to original
canvas->drawImage(jpegHighImage, 210, 0); // Nearly identical, 5x smaller
canvas->drawImage(jpegLowImage, 0, 230);  // Visible block artifacts
canvas->drawImage(webpImage, 210, 230);   // Good quality, smallest size

渲染结果对比

各格式/质量编码后的效果与文件大小差异(同一张 200×200 源图):

Image Codec Specs Result

关键观察:

  • PNG (103 KB):无损格式,像素与原图完全一致,适合需要精确还原的场景。
  • JPEG q=90 (20 KB):体积仅为 PNG 的 1/5,肉眼几乎无法区分与原图的差异。
  • JPEG q=10 (3 KB):体积极小,但可明显观察到块状压缩伪影(Block Artifact),仅适用于缩略图。
  • WebP q=80 (13 KB):在文件大小和画质之间取得了最佳平衡,推荐作为 Web 和移动端的默认选择。
← Bitmap 与像素操作视频与外部纹理 →
  • 1. ImageCodec 统一接口
    • 1.1 支持的格式与识别
    • 1.2 协作流程
  • 2. 解码:MakeFrom 与 readPixels
    • 2.1 探测元数据 (MakeFrom)
    • 2.2 执行解码与下采样 (readPixels)
    • 2.3 Orientation 自动处理
  • 3. 编码:导出与序列化
    • 3.1 编码接口与参数
  • 4. 各平台差异说明
    • 4.1 编码格式支持汇总
    • 4.2 各平台详细对比
    • 4.3 格式自动识别机制
    • 4.4 EXIF 方向元数据处理
    • 4.5 编码质量参数对比
    • 4.6 选择编码格式的建议
  • 5. 代码实战:编码格式对比
    • 渲染结果对比
公司地址:广东省深圳市南山区海天二路33号腾讯滨海大厦Copyright © 2018 - 2026 Tencent. All Rights Reserved.联系电话:0755-86013388隐私政策