大多数浏览器和
Developer App 均支持流媒体播放。
-
在你的 App 中支持 HDR 图像
了解如何在你的 App 中识别、加载、显示和创建高动态范围(HDR)静态图像。探索常见的 HDR 概念,了解 ISO 规范的最新更新。了解如何使用 SwiftUI 和 UIKit 识别和显示 HDR 图像,如何从 ProRAW 和 RAW 捕获中创建 HDR 图像并在 CALayer 中显示。我们还将带你了解 CoreGraphics 对 ISO HDR 的支持,并分享采用 HDR 技术的最佳实践。
资源
- Edit and play back HDR video with AVFoundation
- Editing and Playing HDR Video
- Export HDR media in your app using AVFoundation
- Processing HDR Images with Metal
- Supporting HDR images in your app
相关视频
WWDC23
WWDC22
-
下载
大家好!我叫 Jackson 我是 David 在本讲座中 我将介绍 HDR 图像的一些背景知识 和最近在该领域发布的标准
然后我将介绍 如何使用新的和现有的 API 在 App 中支持这些图像
David 将深入介绍 处理 HDR 图像管线的细节 最后我将围绕 显示高动态范围这一内容 总结一些更高级的主题
让我们来看看 HDR 是如何工作的
在物理世界中 由于人类眼睛的适应能力 我们可感知到巨大的光照范围
相比之下 一个典型的 标准动态范围 (SDR) 显示器 只能产生有限的光照范围 这意味着当捕捉某个场景图像时 必须以某种方式将广范围的光照等级 压缩到较小的 SDR 范围内
使用高动态范围 (HDR) 显示器 你可显示更大范围的光照等级 而无需对其进行压缩 这让你所显示的图像 看起来更像原本的场景 而且更明亮、更鲜艳
我们多年来 一直能够捕捉高动态范围 但在过去 你必须将捕捉到的范围 压缩到 SDR 显示范围内 现在 在 HDR 显示器上显示时 你可将场景 渲染得更像其原本的样子
比如 在这幅雪景上的日出图像中 有一些区域落入真实世界光照等级的 广范围内 在 SDR 显示器上 你只能准确地 表示部分场景 使用 HDR 显示器 你可在不影响对比度的 情况下表现更多的场景
因此 拥有一个具有 HDR 范围的显示器可让我们渲染 比最亮的 SDR 白色 更亮的部分场景 这通常被称为动态余量
在此示例中 基准白色是 SDR 显示器 能产生的最亮白色 超过该基准点的均为动态余量
在过去的讲座中 我们介绍了扩展动态范围 (EDR) 用于具有 HDR 功能的显示器 它可以与该显示器动态余量中 渲染的内容进行交互
在 EDR 范式中 基准白色为 1.0 峰值为显示器可表示的最大值 我今天介绍的 HDR API 使用 EDR 来实现更完整的 高动态范围内容管线
如你想进一步了解 更多 EDR 相关信息 请查阅 “以 EDR 进行高动态范围渲染”讲座
这是 HDR 的一个示例 当书中纸的白色略低于基准白色时 这个坐在窗前的人的 SDR 图像看起来不错 任何更亮的部分 如窗户 就会被衰减或剪掉
但当你可在 HDR 中显示图像时 你可在高亮点处显示更多细节 并在整个场景中 更可靠地保留对比度 这是你支持 HDR 可得到的好处
那为何要支持 HDR 图像? 如果你正在构建一个 App 该 App 中 用户创建或提供的内容是很重要的 支持 HDR 将使用户体验更好
几乎所有 Apple 平台 都提供 HDR 支持 我们引入这些 API 以确保你可充分利用 Apple 极为出色的显示硬件
现在考虑支持 HDR 的另一个重要原因是 Apple 一直在 通过摄影技术委员会 与国际标准化组织进行合作 并于今年发布了 一项新的 HDR 图像技术规范 该规范名为 TS22028-5 它提供了一个结构 可将 HDR 内容 编码到现有静态图像格式中 而不会影响其质量
我将把遵循这一 ISO 规范的 HDR 图像称为“ISO HDR” 以避免与其他形式的 HDR (如 HDR 视频、捕捉或显示) 混淆
回顾我们之前的比例尺 典型的 SDR 图像 包括 sRGB 和 Display P3 将黑色和白色定义为 0.2 和 80 坎德拉每平方米 而 ISO HDR 将黑色 和默认基准白色 分别定义为 0.0005 和 203 超过 203 的 所有光照均为动态余量
那这些新的图像文件中有什么?
规范要求使用 Hybrid Log-Gamma (HLG) 或 Perceptual Quantizer (PQ) 作为编码传输函数 它们在功能上类似于 SDR 图像中使用的伽马曲线
ISO HDR 文件的基色 是 BT.2020 基色 这是一种广色域 色彩空间 迄今仅在视频中常用 为避免色带问题 HDR 图像每个图块至少应为 10 位 这意味着某些格式 如 HEIF 可以编码 HDR 但某些其他格式 如传统的 JPEG 无法符合 22028-5 规范 因为这些格式 仅支持 8 位的图块 对于所需的元数据 传统的 ICC 配置文件 和 CICP 标签都有效 这些要求 共同定义了新的 ISO HDR 文件 与 ISO HDR 文件相关的还有一些 其他可选的 元数据字段也可能与你相关 参考环境标签 定义了内容参考条件的 环境条件
漫反射白光亮度定义了 此内容的基准白色所在的位置 默认值为我之前提到的 203
当 HLG 是传输曲线时 可使用参考场景标签 它定义了图像内容 是参考场景还是参考显示 该标签的默认值 是参考显示
母版和内容色域体积标签 是现有的 HDR 视频所共有的 用于定义图像中 存在的色彩范围的信息
最后 内容光亮等级标签 提供图像中场景的 光亮等级信息
有关 ISO HDR 的更多信息 请查看 ISO 网站上的规范文档
除了 ISO HDR 之外 我非常兴奋地首次向你介绍 如何获取 用 iPhone 拍摄的图像的最佳版本 自 2020 年以来 用户已拍摄了 数万亿张带有额外数据的 iPhone 图像 这使我们能够 从 SDR 图像重建 HDR 表示 我称此类型的 HDR 为“增益图 HDR”
今天 David 和我将向你展示 用于在你的 App 中 访问此 HDR 表示的新 API 让你可选择显示 你的照片图库中已有的任何一代 增益图 HDR 的极佳的 HDR 图像 现在让我们谈谈 如何使用这些新 API 将 HDR 图像合并到 App 中
我要向你展示的 API 在 SwiftUI、 UIKit 和 AppKit 中都可用 让我们看看 SwiftUI 和 UIKit API 在本例中 我可通过 URL 访问 ISO HDR 图像文件 并希望显示该图像 我所要做的 就是创建一个 UIImage 并将其提供给一个图像视图 同时提供新的 allowedDynamicRange 修饰符以启用高动态范围 就是这么简单
同样地 在 UIKit App 中 你可设置新的 UIImageView 属性 “preferredImageDynamicRange” 瞧 这就有了一个 HDR 结果
动态范围属性包括三个选项 用于处理 HDR 内容 这些属性适用于 SwiftUI Image、 UIImage 和 NSImage 视图
high 选项让系统知道 你想显示高动态范围内容 并让我们为你完成 将该内容 映射到当前显示上的繁重工作 包括在显示状态 发生变化时进行更新 请注意如果图像不是 HDR 图像 无论是否使用 dynamicRange 标志 你将获得的体验都是相同的 你可安全地将这些选项 与非 HDR 内容一起使用
standard 选项 禁用高动态范围渲染 而是将所有内容显示为 SDR 也就是说会对超出 SDR 范围的内容进行色调映射 这也是在没有 HDR 功能的显示器上显示图像的方式
最后 当你想仅以 HDR 显示一部分 而不是全部内容时 应使用 constrainedHigh 选项 为何你会 只想显示部分 HDR 而非全部? 好吧 有几个可能的原因
在本例中 我有一个 包含许多图像缩略图的叠放视图 其中一些图像是 HDR 而另一些则不是 如果我使用 high 动态范围选项 你将得到以下结果 一些 HDR 图像非常明亮 但 SDR 图像则并非如此 现在它 看着很沉闷 甚至处于非活跃状态
现在让我们使用 constrainedHigh 选项 通过限制 HDR 内容 允许使用的动态余量 使影片看起来更加统一 你仍可 从 SDR 图像中区分 HDR 图像 但 SDR 图像 看起来不再灰暗或像在非活跃状态 你可能希望为特定图像视图使用 constrainedHigh 或 standard 选项 的另一个原因是 HDR 内容有时可能非常明亮 你可能 不希望用户的注意力被其吸引 而忽视了你的 App 的其他方面 比如 这是一个较小的图像 当使用完整的 HDR 显示时 它看起来 像是 App 中最重要的部分 而让人忽视了重要的控件和信息
在我继续之前 你可能已经注意到 此处的选项均对图像进行色调映射 如果你不希望操作系统 为你执行色调映射 你将需要使用底层 API 我将在本讲座的后面讨论此问题
要记住 HDR 的一个重要方面 是它需要一个管线 该管线不会压缩 或以其他方式降低 HDR 数据 我们今天讨论的 API 都已得到了充分支持 但被废弃的 API 可能没有可安全用于 HDR 的管线 比如 如果你使用被废弃的 UIGraphicsBeginImageContext- WithOptions 调整图像大小 你就会丢失 HDR 和广色域色彩 在创建支持 HDR 的 App 时应避免此情况
如果你正在尝试创建缩略图 UIKit 在 iOS 15 中 引入了 UIImage 的缩略图 API 如果你不需要精确的大小控制 这是获取 HDR 缩略图的推荐方法 如果你需要更精确的控制 或需要支持 iOS 15 之前的版本 UIKit 提供了 UIGraphicsImageRenderer 通过使用 imageRendererFormat UIKit 知道如何构建 一个不会导致图像中 HDR 信息在重绘时丢失的渲染器
让我们看看将图像数据 导入 App 的一种常见方法
PhotoKit 提供了 一个接口供 App 访问照片图库 在我的 App 中 我已将 照片选择器添加到主视图中 凭此可轻松访问用户选择的图像 由于照片选择器可能尝试将图像 转码为不保留 HDR 数据的格式 因此我将使用“current”编码策略 和通用的“images”匹配类型
要了解更多 照片选择器的工作原理 请查看“在你的 App 中 嵌入照片选择器”一讲 使用 ISO HDR 图像 我可从 DataRepresentation 创建 UIImage 并直接在任意 图像视图中使用而无需额外的代码
如果我还支持增益图 HDR 我可使用新的 UIImageReader 在可用时获取 HDR 表示 当在 HDR 显示器上时 此 API 将默认返回 HDR 表示 否则返回 SDR 版本
我们到目前为止所讨论的 API 不依赖于图像是否是 HDR 或是否知道图像是 HDR 回想一下 当你告知一个图像视图 它应该显示高动态范围时 该图像是否为 HDR 都没有关系 然而 你可能会有管线或 App 希望识别图像是否为 HDR
使用 UIKit 你可检查 isHighDynamicRange 属性 以确定其内容是否与 ISO HDR 兼容
使用 AppKit、 CoreGraphics 和 CoreImage 你需要检查图像的 CGColorSpace CGColorSpaceUsesITUR_2100TF 函数 对 ISO HDR 图像的返回值为 true
HDR 图像 可使用广范围的动态余量 比如 目前的 iPhone 生成的图像 使用了至多 8 倍的动态余量 然而 只有一些显示器可显示 HDR 且并非所有 HDR 显示器都相同
iPhone 14 可显示比基准白色 亮度至多亮 8 倍的 HDR 亮点 12.9 英寸的 iPad Pro 和 MacBook Pro 可显示至多 16 倍 而 Pro XDR 显示器 可显示至多 400 倍
大多数其他 Apple 显示器 可显示至多 2 倍的动态余量 然而 这对于大多数 HDR 内容来说可能是不够的 还有一些支持 HDR 功能的外接显示器 这些显示器并没有一个详尽的清单; 然而 有一个 API 可让你确定 当前显示 你的 App 的显示器性能
你可查询 iOS 和 iPad OS 上的 potentialEDRHeadroom 和 macOS 上的 maximumPotentialExtended- DynamicRangeColorComponentValue 以确定用来显示 你的 App 的显示器性能
在我们进入更高级的主题之前 让我们谈谈 何时显示 HDR 是有意义的 正如我所介绍的 HDR 看起来很棒 当显示图像是你的 App 的一个主要部分时 你应该考虑包含对 HDR 的支持 但这有时会让人分散注意力 所以如果你认为 不需要 HDR 带来的额外收益 请考虑使用 constrainedHigh 或 standard 选项
让我们回顾一下 你现在了解了 如何识别 ISO HDR 图像 显示 HDR 图像 从照片图库访问 ISO HDR 和增益图 HDR 以及如何确定 你的显示器是否为 HDR 现在 David 将向你介绍如何阅读、写入 和操作 HDR 图像 谢谢 Jackson 在处理 HDR 图像时 你的 App 可能会 支持一些常见的操作:
从文件或数据中读取 ISO HDR 或增益图 HDR 图像到内存中; 保留 HDR 内容的同时 在内存中修改图像; 在不丢失 HDR 的情况下 从一种图像类转换为另一种图像类; 最后 将 HDR 图像 写入 ISO HDR 文件 功能性 HDR 图像管线的一个关键属性 是图像对象具有关联的色彩空间 比如 CGImage 和 CIImage 对象 都使用 CGColorSpace API 进行此操作 图像可有多种支持的色彩空间 但是 ISO HDR 图像 支持 CGColorSpace 即 ITUR 2100 HLG 或 PQ 有鉴于此 让我们 从如何读取 ISO HDR 图像开始 UIImage 和 NSImage 现在自动支持读取 ISO HDR 图像 色彩同步是 Apple 的色彩管理基础工具 它将处理 HDR ICC 配置文件 并提供适合显示的图像对象
在读取增益图 HDR 图像时 你可创建首选高动态范围的 UIImageReader 配置来请求 HDR 表示 请注意 此新行为 仅影响增益图 HDR 图像 就像 NSImage 和 UIImage 一样 Core Image 自动支持读取 ISO HDR 文件 你只需使用 CIImage 的 contentsOfURL API 即可 生成的 CIImage 对象将自动包含 从文件色彩空间转换 到 Core Image 扩展范围 工作空间的正确配置 当你调试代码时 可使用 Xcode 的 QuickLook 功能来检查图像对象的配置 在本例中 QuickLook 弹出框显示图像是 从 PQ ISO HDR 色彩空间转换而来
你的代码 还可获取 .colorspace 属性 来检查文件的色彩空间
它可能是 SDR 色彩空间 比如 sRGB 或 Display P3 也可能是 HDR 色彩空间
如你更喜欢使用 CoreGraphics API 则可使用 CGImageSourceCreateImageAtIndex 并将新的 decodeRequest 键值 设为 decodeToHDR 也可获得等效行为表现
几分钟前 Jackson 描述了为何你 可能希望将 HDR 图像限制为 SDR
同样地 使用 Core Image 的 App 可能希望覆盖其自动 HDR 支持 以确保图像被色调映射到 SDR 当你希望避免在某些情况下 使用 HDR 比如进行特征检测时 这很有用 要启用此功能 你只需在创建 CIImage 时提供 toneMapHDRtoSDR 选项 在此情况下 返回的 CIImage 对象将包含一个配置步骤 在应用任何其他操作之前 将 HDR 源色调映射到 SDR 范围内
请注意此选项仅在 图像具有 HDR 色彩空间时才有效
生成的 CIImage 看起来与指定使用 dynamicRange.standard 选项的 图像视图相同 此外 使用 CGImageSourceCreateImageAtIndex 并将 decodeRequest 设为 decodeToSDR 效果也与之相同
传统地 增益图 HDR 图像 会在照片 App 中 显示完整的动态范围 但只有 SDR 表示可用于 Core Image 和 ImageIO 等 API 我非常高兴向你描述新的 API 它将允许你的 App 访问 增益图 HDR 图像的全部范围
这个 API 非常简单易用 只需在初始化 CIImage 时 提供 expandToHDR 选项
在此情况下 返回的 CIImage 对象 将包含一个配置 可将主要图像 与增益图相结合来生成 HDR 图像
当照片图库包含额外的 增益图数据以支持此操作时 图像的 .colorspace 属性 将是一个 HDR 色彩空间
这与使用 CGImageSourceCreateImageAtIndex 并将 decodeRequest 键值 设为 decodeToHDR 的作用相同
这些选项也适用于 RAW 文件 现在我将更详细地介绍这些选项
来自 iPhone 的 ProRAW 图像 和来自相机的 RAW 图像 是一种灵活的图像格式 为摄影师提供了重要的创造性控制 包括将部分场景 渲染为 HDR 动态余量的能力 许多 RAW 格式包含大量动态范围 只需将其处理成无约束的形式 让我描述一下其工作原理 首先 如果你的 App 只想显示 RAW 文件的默认 SDR 外观 可像平常一样从 URL 创建图像 但如果你的 App 只想显示默认的 HDR 渲染外观 你只需添加新的 expandToHDR 选项即可
然而 如果你的 App 想要解锁 RAW 的全部功能 你的代码应从 URL 创建一个 CIRAWFilter
如果你只是要求滤镜 提供其输出图像 则会得到默认外观的 CIImage 但此 API 的 关键优势在于可轻松修改滤镜
每个 CIRAWFilter 实例都有几个属性 你的 App 可更改这些属性以更改输出图像 这些属性 在“捕获和处理 ProRAW 图像”讲座中已有详细说明 但让我们回顾一下与此 HDR 讨论 特别相关的一个属性
RAW 图像的动态范围 可以调整为 0-1 的任意值 extendedDynamicRangeAmount 属性 类似于 Jackson 先前描述的 viewDynamicRange 控件
此属性的默认值为 0 这表示输出图像应为 SDR 该属性的最大值为 1 这表示输出图像 应充分使用文件中存在的动态余量 以上总结了 各种读取 ISO HDR 图像的方法 接着 让我们讨论一些 关于如何修改 HDR 图像的建议
Core Image 为处理 HDR 图像 提供了强大而灵活的 API 因为它包含超过 150 个支持 HDR 的 内置滤镜
所有这些滤镜都可生成或处理 包含 HDR 内容的图像
所有这些滤镜都可正常工作 因为 Core Image 工作色彩空间 是未被压缩且线性的 允许 RGB 值 超出 0-1 的范围
在你开发你的 App 时 可检查给定滤镜是否支持 HDR 为此 你可创建一个滤镜实例 然后询问滤镜属性的类别 接着检查数组 是否包含高动态范围类别 请观看“使用 Core Image、Metal 和 SwiftUI 显示 EDR 内容”一讲 查看内置 CI 滤镜 和自定义 CI 内核的更多信息 接着 让我们讨论将 HDR 图像写入 ISO HDR 文件的方法 通常 你的 App 想将内存中的图像对象 写入新的文件表示 传统地 使用 UIImage、 jpegData 和 pngData API 会保存 8 位精度的 SDR 图像
今年新增功能是 当对象包含 HDR 内容时 UIImage 可使用 16 位 PNG 或 10 位 HEIF 格式 自动写入 ISO HDR 图像 如果原始图像是 增益图 HDR 图像 则其还将转换为 ISO HDR
同样地 当你指定 HDR 色彩空间 并调用 writePNGRepresentationOfImage 请求 RGBA16 格式时 Core Image 可写入一个 HDR PNG 文件
或者当你指定 HDR 色彩空间并调用 writeTIFFRepresentationOfImage 请求 RGBA16 格式时 Core Image 可写入一个 HDR TIFF 文件 注意 PNG 和 TIFF 都使用无损压缩 这会导致更大的文件大小
因此 最佳实践是使用 writeHEIF10RepresentationOfImage 写入 HEIF 文件 并指定 HDR 色彩空间
有时你也可能需要 从一个框架类转换到另一个框架类 或从一个色彩空间 转换到另一个色彩空间
在 UIImage、CIImage、CGImage、 IOSurface 和 CVPixelBuffer 这些图像类之间进行转换的过程 大体上都相同 话虽如此 在使用 HDR 管线时 有几件事情需要注意
首先让我们讨论转换为 IOSurface 或 CVPixelBuffer 对象 这种图像类型很有用 因为 比如该类型 可被用作 CALayer 的内容 它还可容纳双平面色度子采样图像 有效节省内存 在你使用 CVPixelBuffer 之前 请确保声明 它具有 ISO HDR 兼容内容 第一步是创建 适当格式的像素缓冲区 比如 10 位双平面全范围格式
在此过程中 为了获得最佳性能 请提供 IOSurfacePropertiesKey 确保指定缓冲区 为 surface-backed
接着 请确保向 CVPixelBuffer 添加 attachments 以便系统知道其包含 ISO HDR 兼容的色彩空间属性 一旦你拥有了 CVPixelBuffer 将其转为 CIImage 就是小菜一碟 只需调用 CIImage 的 withCVPixelBuffer API 即可 你可使用 CIContext 渲染到缓冲区 将 CIImage 转换为 CVPixelBuffer
接着 在一些情况下 你的 App 可能需要 在 Core Image 和 CGImageRef API 之间进行转换
如果你希望 此转换保留 HDR 内容 你应选择一个 HDR 色彩空间 并请求深度像素格式 比如 RGBA16 或 RGBAh 格式
今年新推出的 CoreImage 新增了 RGB10 格式 它是深度格式 但仅使用一半内存
将 CIImage 转换为 CGImage 非常方便 因为 CGImages 在各种 API 中广泛得到支持 但要注意 为了使用户交互式渲染的 性能达到最佳 不建议这样做 为了获得最快的性能 最好让 CoreImage 直接渲染到 MTKView 或通过 PixelBuffer 渲染到 CALayer
说到 CALayer 让我们交回给 Jackson 来更多了解执行更复杂的工作流程时 你可能需要的的底层 API 谢谢 David! 当你需要最佳渲染性能 或更好地控制你的内容 如何合成到你的 App 中时 CALayer 是一个强大的工具 要在 CALayer 上启用 HDR 渲染 你现在可设置 wantsExtendedDynamicRangeContent 属性 这类似于 CAMetalLayer 所使用的属性 以便在你显示器的 动态余量中显示内容
这两种方法之间的关键区别在于 CALayer 属性 启用图层内容的色调映射 而 CAMetalLayer 则不会 在实践中这意味着什么?
这张图像和图谱 显示了 10 倍动态余量的内容 当该内容被渲染到至少有 10 倍动态余量可用的显示器上时 两个图层的行为表现完全相同 现在假设显示器 只有 5 倍动态余量可用
在使用 CAMetalLayer 的情况下 超过 5 倍的图像数据 将被压缩在显示器可显示的范围内 导致图像出现特别明显的不连续性
在使用 CALayer 的情况下 图像将 进行色调映射 以避免不连续性 所使用的色调映射算法 取决于 与该图像一起使用的传输曲线 有关这些算法的更多信息 你可参考 HLG 和 PQ 的 ITU 标准
CALayers 提供了一种快速简单的 方法将 HDR 内容显示到屏幕上 因为 CAMetalLayers 让你 可自由地创建自己的色调映射管线 要直接使用 CALayer 渲染 HDR 你必须使用这些可用类之一: 被恰当标记为 ISO HDR 类型的 CGImage、CVPixelBuffer 或 IOSurface 对象 CALayer 将对这些对象 进行渲染和色调映射 如要直接使用 CALayer 并且不使用这些类之一 则你可采用刚才 David 描述的方法之一对其进行转换
在使用 HDR 工作流程时 使用正确的像素格式非常重要 这些像素格式 在处理 HDR 数据时可安全使用 16 位和 32 位浮点格式 始终支持高动态范围 16 位的整数格式 也将在适当的文件格式和环境下 支持 HDR 内容 最后 当内存和文件大小很重要时 可使用 10 位像素格式 这是大多数压缩的 ISO HDR 图像的默认位深 在创建可用于 HDR 内容的 CGImage 时 还有 CoreGraphics 标志 与前面的列表一样 你可使用浮点、半浮点、 16 位整数和 10 位 RGB
在介绍像这样的新功能时 最后一个重要的主题是 向下兼容性 在处理 HDR 图像时 你可以做什么 来支持旧版本的 iOS 和 macOS? 对于 ISO HDR 图像 CoreImage 提供了 toneMapHDRtoSDR 选项 可将 HDR 转换为 SDR 同样地 在使用 CoreGraphics CGContext 进行渲染时 你可设置一个 SDR CGColorspace 目标 图像将被色调映射到该空间 对于增益图 HDR 请使用版本检查来控制 何时使用新的 expandToHDR 选项 当省略这些选项时 将始终加载 SDR 版本的文件 而非 HDR 版本 总结一下 我们介绍了用于读取、 写入和显示 HDR 图像的新 API 向你展示了 如何访问增益图 HDR 表示 并给你提供了 API 用于与完全 具备 HDR 功能的管线一起工作
我们迫不及待地 想看到你用 HDR 做出优秀的作品! 一起:感谢你的观看!
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。