这个是我在开发项目中的一个模块所需要用到的通用工具类,所有代码都贴在下面了,以帮助有需求的开发者能够按需直接取用,以节约开发者找资料的时间。

能力预览:

Resource => Base64(string)

PixelMap => Base64(string)

uri(来自系统相册)=> Base64(string)

Resource => PixelMap

从系统相册获取一张图片的uri

通过一个PixelMap(就是指向PixelMap资源的地址)克隆出一个PixelMap(克隆一份PixelMap资源,并且返回该资源的地址)(坑点:PixelMap如果赋值给新变量,是不会创建一个新的PixelMap的,新旧变量都会指向同一个PixelMap资源)

uri => PixelMap

imageSource => PixelMap

这里我就简单介绍一下这个工具类都提供了哪些能力:

  1. resource2Base64:接收一个资源(Resource)对象,将其转换成Base64编码的字符串。这个方法内部会先将资源转换为PixelMap对象,然后再将PixelMap对象转换成Base64编码。

  2. pixelMap2Base64:接收一个PixelMap对象,将其转换成Base64编码的字符串。这个过程涉及到将PixelMap打包成JPEG格式的图片,然后使用buffer转换成Base64。

  3. uri2Base64:接收一个图片的URI字符串,将其转换成Base64编码的字符串。这个方法首先将URI转换成PixelMap对象,然后再转换成Base64编码。

  4. resource2PixelMap:接收一个资源(Resource)对象,将其转换成PixelMap对象。这个转换过程涉及到从资源管理器获取媒体内容,并创建一个PixelMap。

  5. getImageUrisFromAlbum:从相册中选择照片,并返回选中照片的URI字符串。这个方法提供了选择照片数量的参数,并返回第一个选中照片的URI。

  6. createPixelMapByClone:接收一个PixelMap对象,创建并返回一个新的PixelMap对象,这是一个深拷贝的过程。可以指定新的像素格式,如果不指定,则使用原始PixelMap的像素格式。

  7. uri2PixelMap:接收一个图片的URI字符串,将其转换成PixelMap对象。这个方法通过打开文件描述符来创建图片资源,并最终创建PixelMap。

  8. imageSource2PixelMap:接收一个ImageSource对象,将其转换成PixelMap对象。这个方法获取图片信息,并根据这些信息创建PixelMap。

import { image } from '@kit.ImageKit';
import { buffer } from '@kit.ArkTS';
import { fileIo, picker } from '@kit.CoreFileKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

class MediaOperate {
  /**
   * 将resource转成base64编码
   * @param res
   * @returns 
   */
  static async resource2Base64(res: Resource): Promise<string> {
    try {
      const pixelMap = await MediaOperate.resource2PixelMap(res)
      // 将PixelMap转换成base64
      const base64 = await MediaOperate.pixelMap2Base64(pixelMap)
      return base64
    } catch (error) {
      AlertDialog.show({
        message: 'createBase64ByResource —— base64编码生成失败:\n' + JSON.stringify(error, null, 2)
      })
      return ''
    }
  }

  /**
   * 将pixelMap转成Base64编码
   * @param pixelMap
   * @returns 
   */
  static async pixelMap2Base64(pixelMap: PixelMap): Promise<string> {
    try {
      let base64Str = ''
      // 转换成base64
      const imagePackerApi: image.ImagePacker = image.createImagePacker();
      let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 100 };
      const data = await imagePackerApi.packing(pixelMap, packOpts)
      let buf: buffer.Buffer = buffer.from(data);
      base64Str = 'data:image/jpeg;base64,' + buf.toString('base64', 0, buf.length);
      hilog.info(0, 'MediaOperate', `pixelMap2Base64 Success To Create Base64: \n ${base64Str}`)
      return base64Str
    } catch (error) {
      hilog.error(0, 'MediaOperate', `pixelMap2Base64 Failed To Create Base64: \n' ${JSON.stringify(error, null, 2)}`)
      return ''
    }
  }

  /**
   * 将uri转成base64编码
   * @param uri
   * @returns 
   */
  static async uri2Base64(uri: string): Promise<string> {
    const pixelMap = await MediaOperate.uri2PixelMap(uri)
    if (pixelMap) {
      const base64Str = await MediaOperate.pixelMap2Base64(pixelMap)
      hilog.info(0, 'MediaOperate', `uri2Base64 Success To Create Base64: ${base64Str}`)
      return base64Str
    } else {
      return ''
    }
  }

  /**
   * 将Resource转换成PixelMap
   * @param res
   * @returns 
   */
  static async resource2PixelMap(res: Resource): Promise<PixelMap> {
    // 资源管理器
    let resourceManager = getContext().resourceManager
    // 通过resource创建Uint8Array
    let imageArray = await resourceManager.getMediaContent(res);
    let pixelBuffer = new Uint8Array(imageArray).buffer as Object as ArrayBuffer;
    let imageResource = image.createImageSource(pixelBuffer);
    let pixelMap = await imageResource.createPixelMap({ editable: true });
    return pixelMap
  }

  /**
   * 选择照片
   * @param photoNum
   * @returns 
   */
  static async getImageUrisFromAlbum(photoNum: number = 1): Promise<string> {
    try {
      const photo = new picker.PhotoViewPicker()
      const result = await photo.select({
        maxSelectNumber: photoNum,
        MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE
      })
      return result.photoUris[0]
    } catch (error) {
      AlertDialog.show({
        message: '选取相册图片uris失败:\n' + JSON.stringify(error, null, 2)
      })
      return ''
    }
  }

  /**
   * 深拷贝——复制pixelMap创建一个新的pixelMap
   * @param pixelMap
   * @param desiredPixelFormat
   * @returns 
   */
  static async createPixelMapByClone(pixelMap: PixelMap, desiredPixelFormat?: image.PixelMapFormat): Promise<PixelMap> {
    // 获取当前PixelMap的图片信息。
    const imageInfo = pixelMap.getImageInfoSync();
    // 读取当前PixelMap的图像像素数据,并按照当前PixelMap的像素格式写入缓冲区数组。
    const buffer = new ArrayBuffer(pixelMap.getPixelBytesNumber());
    pixelMap.readPixelsToBufferSync(buffer);
    // 根据当前PixelMap的图片信息,生成初始化选项。
    const options: image.InitializationOptions = {
      // 当前PixelMap的像素格式。
      srcPixelFormat: imageInfo.pixelFormat,
      // 新PixelMap的像素格式。
      pixelFormat: desiredPixelFormat ?? imageInfo.pixelFormat,
      // 当前PixelMap的尺寸大小。
      size: imageInfo.size
    };
    // 根据初始化选项和缓冲区数组,生成新PixelMap。
    return image.createPixelMapSync(buffer, options)
  }

  /**
   * uri 转 pixelmap
   * @Param uri
   * @returns
   */
  static async uri2PixelMap(uri: string): Promise<PixelMap> {
    const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
    const imageSource = image.createImageSource(file.fd); // 通过文件描述符创建图片资源
    const imageInfo: image.ImageInfo = await imageSource.getImageInfo();
    const height = imageInfo.size.height;
    const width = imageInfo.size.width;
    const options: image.DecodingOptions = {
      editable: true,
      desiredSize: { height, width }
    };
    const pixelMap: PixelMap = await imageSource.createPixelMap(options);
    fileIo.closeSync(file)
    return pixelMap
  }

  /**
   * source 转 pixmap
   * @param ImageSource
   * @returns
   */
  static async imageSource2PixelMap(imageSource: image.ImageSource): Promise<PixelMap> {
    const imageInfo: image.ImageInfo = await imageSource.getImageInfo();
    const height = imageInfo.size.height;
    const width = imageInfo.size.width;
    const options: image.DecodingOptions = {
      editable: true,
      desiredSize: { height, width }
    };
    const pixelMap: PixelMap = await imageSource.createPixelMap(options);
    return pixelMap
  }
}

export { MediaOperate }

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐