# 为什么系统相册无法加载大图且解码也报错

#### 问题现象

应用侧保存分辨率40320x25200大图到系统相册无法正常加载，且无法正常使用图片解码，如下图所示。

#### 背景知识

正常操作应用，观察运行过程中的应用内存变化情况。当在一段时间内应用内存没有明显增加或者在内存上涨后又逐渐回落至正常水平，则基本可以排除应用存在内存问题；反之，在一段时间内不断上涨且无回落或者内存占用明显增长超出预期，那么则可初步判断应用可能存在内存问题。可参考ArkTS内存泄漏分析。

#### 问题定位

测试使用代码如下：

```
async createPixel() {
  const resourceManager = this.getUIContext().getHostContext()?.resourceManager;
  const imageData = await resourceManager!.getMediaContent($r('app.media.startIcon').id);
  let arrayBuffer = imageData.buffer;
  const imageSource = image.createImageSource(arrayBuffer);
  console.info('createImageSource success')
  let imageInfo = imageSource.getImageInfoSync(0);
  let width = imageInfo.size.width;
  let height = imageInfo.size.height;
  const opts: image.DecodingOptions = {
    editable: true,
    desiredSize:{width:width,height:height},
    desiredPixelFormat: image.PixelMapFormat.BGRA_8888
  };
  let pixel = await imageSource.createPixelMap(opts);
  console.info('createPixelMap success')
  const imagePackerApi: image.ImagePacker = image.createImagePacker()
  let packOpts: image.PackingOption = {
    format:'image/jpeg',
    quality:100
  }
  try{
    imagePackerApi.packToData(pixel,packOpts).then(()=>{
      console.info('imagePacking success')
    })
  }catch (err){
    console.error('imagePacking failed',err)
  }
  console.info('imagePacking complete')
}
```

如下图所示：

可以看到使用超大图解码后，Heap存在明显上涨且长时间无回落。查询日志相关信息，通过日志发现尽管图片解码实例创建成功，但后续创建PixelMap以后的程序并未顺利执行，日志打印如下所示。

#### 分析结论

当图片分辨率过大（像素数超过4亿）时，此时解码占用内存高，触发严重的整机性能问题。图片分辨率降低后可以在图库中正常显示且解码正常。

#### 修改建议

HarmonyOS的图片解码对图片分辨率及文件占用的空间有限制，分辨率越高占用的空间就越大，单张图片的文件占用空间大小不能超过2G，因为单个应用运行内存占用达到4G会触发整机性能问题。建议在图片解码前将图片压缩到指定大小，既可展示图片，又可以保证系统的稳定运行。正常日志打印效果如下：

#### 常见FAQ

Q：超大图加载会非常耗内存，以至于卡顿卡死等情况，有什么优化的方案？

A：解码参数DecodingOptions有两个属性desiredRegion和desiredSize可以控制解码的区域以及输出的大小，同时传递两个属性需进一步传入cropAndScaleStrategy参数指定缩放与裁剪的先后顺序，推荐设置CROP\_FIRST。