目录

如何获取PixelMap图像的文件大小

问题现象

在编辑PixelMap时,由于PixelMap在动态的修改,有什么方法可以获取到PixelMap图像的大小。

背景知识

解决方案

获取PixelMap的文件大小可以通过以下两种方案:
  • 使用getPixelBytesNumber方法获取图像像素的总字节数,需要注意的是该方法得到的是位图占的字节数。在对PixelMap进行处理前,需要使用createImageSource获取图片的ArrayBuffer,并创建新的PixelMap实例。
  • 可使用ImagePacker的packToData方法,将PixelMap图片进行编码,从而获取到图片文件的大小。使用方式和效果图如下:

完整示例参考如下:

import { image } from '@kit.ImageKit';

@Entry
@Component
struct Page {
  @State pixelMap: PixelMap | undefined = undefined;

  saveToData() {
    let packOpts: image.PackingOption = { format: 'image/png', quality: 100 };
    const imagePackerApi: image.ImagePacker = image.createImagePacker();
    imagePackerApi.packToData(this.pixelMap, packOpts)
      .then((data: ArrayBuffer) => {
        console.info(`packToData后的文件大小:${data.byteLength.toString()}`);
      });
  }

  CreatePixelMap() {
    this.getUIContext().getHostContext()?.resourceManager.getMediaContent($r('app.media.startIcon').id).then((data) => {
      // 提取图片数据的缓冲区
      let arrayBuffer = data.buffer.slice(data.byteOffset, data.byteLength + data.byteOffset);
      // 创建ImageSource对象
      let imageSource = image.createImageSource(arrayBuffer);
      // 设置初始化选项
      let opts: image.InitializationOptions = { editable: true, pixelFormat: 3, size: { height: 6, width: 6 } };
      // 创建PixelMap
      imageSource.createPixelMap(opts, (err, pixelMap) => {
        if (err) {
          console.error(`Failed to create pixelmap. code is ${err.code}, message is ${err.message}`);
        }
        this.pixelMap = pixelMap;
      });
    });
  }

  aboutToAppear(): void {
    this.CreatePixelMap();
  }

  build() {
    Column() {
      Image(this.pixelMap)
        .width(200)
        .height(200)
        .borderWidth(1);
      Button('点击').onClick(() => {
        if (this.pixelMap) {
          // 获取PixelMap的像素字节数
          let pixelBytesNumber: number = this.pixelMap.getPixelBytesNumber();
          console.info(`PixelMap像素的总字节数:${pixelBytesNumber.toString()}`);
        }
      });
      Button('点击').onClick(() => {
        this.saveToData();
      });
    }
    .width('100%')
    .height('100%');
  }
}

效果预览:

常见FAQ

Q:通过getPixelBytesNumber方法获取到的图片大小和实际图片大小相差较大。

A:图片解码内存占用是宽 * 高 * 像素字节数,默认是rgba格式即一个像素占用四字节,所以通过getPixelBytesNumber方法获取到的图片大小为宽 * 高 * 4。

Q:ImageInfo中的stride表示什么含义?getPixelBytesNumber获取到的字节数和通过height乘以stride得到的数值为什么不同?

A:ImageInfo中的stride表示图片跨距,内存中每行像素所占的空间。stride通常满足:stride≥图像宽度×每像素字节数。getPixelBytesNumber是获取图像像素的总字节数。图像像素总字节数=图像高度x图像宽度x每像素字节数。所以图像像素总字节数小于等于height*stride。

Q:packToData方法执行时提示未定义。

A:packToData方法在API13以上才提供,需要系统升级到对应版本以上才能使用该方法。

Q:packToFile方法执行时提示62980115。

A:packToFile接口使用Promise形式时,无返回结果,需按接口规范使用。