图片区域解码与下采样(C/C++)
=================

应用在处理大尺寸图片时，直接解码整张图片可能导致内存占用过高和解码耗时较长。通过区域解码和下采样解码功能，可以有效优化这一场景：

*   **区域解码**：仅解码图片的指定矩形区域，适用于需要查看图片局部的场景。
*   **下采样解码**：按期望尺寸解码图片，解码器自动选择最优采样率，适用于大图预览场景。

**适用场景**：

| 场景 | 推荐方式 | 说明 |
| :-- | :-- | :-- |
| 图片局部放大查看 | 区域解码 | 只解码需要查看的区域。 |
| 大图预览（如4K图片在手机屏幕显示） | 下采样解码 | 降低分辨率，减少内存占用。 |
| 地图/全景图瓦片加载 | 组合使用 | 指定区域并指定输出尺寸。 |

#### 区域解码

区域解码通过设置解码参数cropRegion，指定需要解码的矩形区域。解码器仅解码该区域的数据。参数详情请参考[Image\_Region](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-image-nativemodule-image-region)。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f5/v3/C3Wi6xzOR0KVT6hsN1H_kw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073519Z&HW-CC-Expire=86400&HW-CC-Sign=0CD2A67F742AC9AAACDEB651E83556133398018C07306EE8D4E21F120BA0C690)

Native C版本区域解码需使用OH\_DecodingOptions\_SetCropRegion接口，而非SetDesiredRegion。SetDesiredRegion接口不生效。

#### \[h2\]开发步骤

1.  参考[使用Image\_NativeModule完成图片解码](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/image-source-c)创建OH\_ImageSourceNative实例。
    
2.  设置cropRegion参数执行区域解码。
    
    // 区域解码示例。
    napi\_value DecodeRegion(napi\_env env, napi\_callback\_info info)
    {
        OH\_DecodingOptions \*ops = nullptr;
        OH\_DecodingOptions\_Create(&ops);
        
        // 设置裁剪区域参数，使用SetCropRegion实现区域解码。
        Image\_Region region = {
            .x = 0,
            .y = 0,
            .width = 1000,
            .height = 1000
        };
        OH\_DecodingOptions\_SetCropRegion(ops, &region);
        
        OH\_PixelmapNative\_Release(g\_thisImageSource->resPixMap);
        g\_thisImageSource->resPixMap = nullptr;
        
        Image\_ErrorCode errCode = OH\_ImageSourceNative\_CreatePixelmap(g\_thisImageSource->source,
                                                                      ops, &g\_thisImageSource->resPixMap);
        OH\_DecodingOptions\_Release(ops);
        ops = nullptr;
        
        if (errCode != IMAGE\_SUCCESS) {
            OH\_LOG\_ERROR(LOG\_APP, "DecodeRegion failed, errCode: %{public}d.", errCode);
            return GetJsResult(env, errCode);
        }
        OH\_LOG\_INFO(LOG\_APP, "DecodeRegion succeeded.");
        return GetJsResult(env, errCode);
    }
    

#### \[h2\]使用限制

*   区域坐标和大小必须在原图范围内。
*   区域大小必须为正整数。

#### 下采样解码

下采样解码通过设置解码参数desiredSize，指定期望输出的图片尺寸。解码器会根据期望尺寸输出PixelMap，减少最终的内存占用。

**解码处理差异**：

*   **JPEG、PNG、HEIF格式**：解码过程中采用下采样策略，按最优采样率解码，解码效率更高。
*   **其他格式**：先完整解码原图，再缩放至期望尺寸。

参数详情请参考[OH\_DecodingOptions](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-image-nativemodule-oh-decodingoptions)。

#### \[h2\]开发步骤

1.  参考[图片开发指导(C/C++)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/image-source-c)创建OH\_ImageSourceNative实例。
    
2.  设置desiredSize参数执行下采样解码。
    
    // 下采样解码示例。
    napi\_value DownsampleDecode(napi\_env env, napi\_callback\_info info)
    {
        OH\_DecodingOptions \*ops = nullptr;
        OH\_DecodingOptions\_Create(&ops);
        
        // 设置期望输出大小参数。
        Image\_Size desiredSize = {
            .width = 512,
            .height = 512
        };
        OH\_DecodingOptions\_SetDesiredSize(ops, &desiredSize);
        
        OH\_PixelmapNative\_Release(g\_thisImageSource->resPixMap);
        g\_thisImageSource->resPixMap = nullptr;
        
        Image\_ErrorCode errCode = OH\_ImageSourceNative\_CreatePixelmap(g\_thisImageSource->source,
                                                                      ops, &g\_thisImageSource->resPixMap);
        OH\_DecodingOptions\_Release(ops);
        ops = nullptr;
        
        if (errCode != IMAGE\_SUCCESS) {
            OH\_LOG\_ERROR(LOG\_APP, "DownsampleDecode failed, errCode: %{public}d.", errCode);
            return GetJsResult(env, errCode);
        }
        OH\_LOG\_INFO(LOG\_APP, "DownsampleDecode succeeded.");
        return GetJsResult(env, errCode);
    }
    

#### 区域解码与下采样组合使用

当同时设置cropRegion和desiredSize时，需要通过cropAndScaleStrategy参数指定裁剪与缩放的先后顺序。

#### \[h2\]cropAndScaleStrategy策略

| 策略 | 常量值 | 操作顺序 | 说明 |
| :-- | :-- | :-- | :-- |
| IMAGE\_CROP\_AND\_SCALE\_STRATEGY\_SCALE\_FIRST | 1 | 先缩放，再裁剪。 | \- |
| IMAGE\_CROP\_AND\_SCALE\_STRATEGY\_CROP\_FIRST | 2 | 先裁剪，再缩放。 | 推荐使用，可减少解码峰值内存。 |

**推荐使用CROP\_FIRST**：先裁剪再缩放可精确控制裁剪区域，保证不同格式解码效果一致。

参数详情请参考[Image\_CropAndScaleStrategy](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-image-source-native-h#image_cropandscalestrategy)。

#### \[h2\]开发步骤

1.  参考[图片开发指导(C/C++)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/image-source-c)创建OH\_ImageSourceNative实例。
    
2.  同时设置cropRegion、desiredSize和cropAndScaleStrategy参数。
    
    // 区域解码与下采样组合使用示例。
    napi\_value CombinedDecode(napi\_env env, napi\_callback\_info info)
    {
        OH\_DecodingOptions \*ops = nullptr;
        OH\_DecodingOptions\_Create(&ops);
        
        Image\_Region region = {
            .x = 1000,
            .y = 500,
            .width = 2000,
            .height = 2000
        };
        OH\_DecodingOptions\_SetCropRegion(ops, &region);
        
        Image\_Size desiredSize = {
            .width = 512,
            .height = 512
        };
        OH\_DecodingOptions\_SetDesiredSize(ops, &desiredSize);
        
        OH\_DecodingOptions\_SetCropAndScaleStrategy(ops, IMAGE\_CROP\_AND\_SCALE\_STRATEGY\_CROP\_FIRST);
        
        OH\_PixelmapNative\_Release(g\_thisImageSource->resPixMap);
        g\_thisImageSource->resPixMap = nullptr;
        
        Image\_ErrorCode errCode = OH\_ImageSourceNative\_CreatePixelmap(g\_thisImageSource->source,
                                                                      ops, &g\_thisImageSource->resPixMap);
        OH\_DecodingOptions\_Release(ops);
        ops = nullptr;
        
        if (errCode != IMAGE\_SUCCESS) {
            OH\_LOG\_ERROR(LOG\_APP, "CombinedDecode failed, errCode: %{public}d.", errCode);
            return GetJsResult(env, errCode);
        }
        OH\_LOG\_INFO(LOG\_APP, "CombinedDecode succeeded.");
        return GetJsResult(env, errCode);
    }
    

#### 注意事项

*   同时设置cropRegion和desiredSize时，建议设置cropAndScaleStrategy为IMAGE\_CROP\_AND\_SCALE\_STRATEGY\_CROP\_FIRST，以保证解码效果一致。
*   对于原始像素内存超过2GB的图片，建议使用下采样解码避免内存溢出。