在鸿蒙应用开发中,图片作为最核心的视觉元素之一,其处理流程的性能和体验至关重要。鸿蒙Next提供了一套强大而统一的图片框架(Image Framework),为开发者提供了从加载到显示,从编辑到保存的全链路能力。本文将深入探讨图片开发的四个关键环节:解码、编码、编辑处理接收,并通过代码示例展示如何高效地完成相关任务。

一、图片解码:高效的图片加载与显示

图片解码是将压缩的图片数据(如JPEG、PNG)转换为系统可识别和渲染的像素数据(PixelMap)的过程。鸿蒙Next的@ohos.multimedia.image模块让这个过程变得简单且高性能。

核心能力:

  • 多格式支持:全面支持JPEG、PNG、WEBP、GIF、BMP、HEIF等主流格式。

  • 渐进式与动图解码:支持JPEG渐进式加载和GIF动图的流畅播放。

  • 精准采样与缩放:可在解码时直接指定采样率或目标尺寸,减少内存占用,这是避免OOM(内存溢出)的关键技巧。

实战代码:从资源文件解码并显示

typescript

import image from '@ohos.multimedia.image';
import { BusinessError } from '@ohos.base';

@Entry
@Component
struct ImageDecodeSample {
  // 用于在UI中展示的PixelMap对象
  @State pixelMap: image.PixelMap | undefined = undefined;

  aboutToAppear() {
    // 1. 创建ImageSource对象,来源可以是资源、文件、ArrayBuffer等
    const imageSourceApi = image.createImageSource($r('app.media.example.jpg').id);
    
    // 2. 设置解码参数:希望输出的尺寸
    let decodingOptions: image.DecodingOptions = {
      desiredSize: { width: 200, height: 200 } // 直接解码为200x200的图,节省内存
    };

    // 3. 异步解码,获取PixelMap
    imageSourceApi.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
      this.pixelMap = pixelMap;
      console.log('图片解码成功');
    }).catch((error: BusinessError) => {
      console.error(`解码失败,错误码:${error.code}, 信息:${error.message}`);
    });
  }

  build() {
    Column() {
      if (this.pixelMap) {
        // 使用PixelMap给Image组件赋值
        Image(this.pixelMap)
          .width(200)
          .height(200)
      } else {
        LoadingProgress() // 解码未完成时显示加载动画
      }
    }
    .width('100%')
    .height('100%')
  }
}
二、图片编码:保存与分享

图片编码是将处理后的PixelMap对象压缩为指定格式文件的过程,常用于保存图片到相册或分享给其他应用。

核心能力:

  • 格式转换:支持将PixelMap编码为JPEG、PNG、WEBP等格式。

  • 质量参数可控:对于JPEG等有损格式,可以灵活设置压缩质量。

实战代码:将PixelMap编码为JPEG并保存

typescript

import image from '@ohos.multimedia.image';
import fileIo from '@ohos.file.fs'; // 文件系统模块

async function encodeAndSaveImage(pixelMap: image.PixelMap) {
  // 1. 创建ImagePacker对象,用于编码
  let imagePackerApi = image.createImagePacker();

  // 2. 设置编码选项:格式和质量
  let packOptions: image.PackingOptions = {
    format: "image/jpeg",
    quality: 85 // 质量范围1-100,值越大质量越好文件越大
  };

  try {
    // 3. 进行编码,获取ArrayBuffer数据
    let data: ArrayBuffer = await imagePackerApi.packing(pixelMap, packOptions);

    // 4. 将ArrayBuffer数据写入文件
    let filePath = `/path/to/your/saved_image.jpg`; // 替换为实际可写的路径
    let file = await fileIo.open(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
    await fileIo.write(file.fd, data);
    await fileIo.close(file.fd);

    console.log('图片保存成功:' + filePath);
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`编码或保存失败:${err.code}, ${err.message}`);
  }
}
三、图片编辑和处理:释放创造力

这是最富有趣味和挑战性的环节,鸿蒙Next通过Image Kit (@ohos.multimedia.imageKit) 提供了丰富的编辑能力。

核心能力:

  • 基础调整:旋转、裁剪、缩放。

  • 滤镜与调色:应用LUT滤镜,调整亮度、对比度、饱和度等。

  • AI增强:智能抠图、人像美颜、图像超分等(部分为高级API)。

实战代码:应用滤镜并裁剪

typescript

import imageKit from '@ohos.multimedia.imageKit';

async function editImage(sourcePixelMap: image.PixelMap): Promise<image.PixelMap> {
  try {
    // 1. 应用滤镜
    let filterOptions: imageKit.FilterOptions = {
      filter: imageKit.FilterType.FILTER_SNOW // 例如,使用“雪”滤镜
    };
    let filteredPixelMap: image.PixelMap = await imageKit.filter(sourcePixelMap, filterOptions);

    // 2. 进行裁剪
    let region: image.Region = { // 定义裁剪区域
      x: 50,
      y: 50,
      size: {
        height: 300,
        width: 300
      }
    };
    let croppedPixelMap: image.PixelMap = await imageKit.crop(filteredPixelMap, region);

    return croppedPixelMap;
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`图片编辑失败:${err.code}, ${err.message}`);
    // 失败则返回原图
    return sourcePixelMap;
  }
}
四、图片接收:处理外部传入的图片

当应用需要接收来自其他应用(如相册、文件管理器、分享菜单)的图片时,需要使用WantFile相关能力。

核心能力:

  • 统一数据管理:通过ohos.app.ability.wantConstant定义的行为(Action)来接收数据。

  • 安全的文件访问:通过Uri安全地访问其他应用提供的图片文件。

配置与实战:使应用能够接收图片

1. 在module.json5中配置Ability的skills,使其响应分享动作。

json

"skills": [
  {
    "entities": ["entity.system.home"],
    "actions": [
      "ohos.want.action.selectMedia", // 选择媒体文件的行为
      "ohos.want.action.sendData"     // 发送数据的行为(如分享)
    ],
    "uris": [
      {
        "type": "image/*" // 指定可接收的文件类型为所有图片
      }
    ]
  }
]

2. 在EntryAbility中接收并处理图片数据。

typescript

import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import Want from '@ohos.app.ability.Want';

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage) {
    // ... 其他初始化代码
  }

  // 当Ability被创建时,通过want参数接收数据
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
    // 判断want中是否包含图片Uri
    if (want.uri && want.uri.length > 0) {
      let receivedImageUri = want.uri;
      console.log(`接收到图片URI: ${receivedImageUri}`);

      // 将URI传递给Page,由Page进行解码和显示
      AppStorage.setOrCreate<string>('receivedImageUri', receivedImageUri);
    }
  }
}

3. 在Page中根据Uri解码图片。

typescript

// 在Page的aboutToAppear或自定义函数中
let receivedUri: string = AppStorage.get<string>('receivedImageUri');
if (receivedUri) {
  // 使用Uri创建ImageSource
  const imageSourceApi = image.createImageSource(receivedUri);
  imageSourceApi.createPixelMap().then((pixelMap: image.PixelMap) => {
    // 获取到PixelMap,可以显示或编辑
    this.receivedPixelMap = pixelMap;
  });
}
总结

鸿蒙Next的图片框架构建了一条清晰、高效的开发路径:

  1. 解码:使用createImageSourcecreatePixelMap,注重性能和内存。

  2. 编码:使用createImagePackerpacking,灵活控制输出格式和质量。

  3. 编辑:使用Image Kit,轻松实现从基础到AI级的复杂效果。

  4. 接收:通过配置skills和解析want.uri,实现流畅的应用间协作。

掌握这四大模块,你就能在鸿蒙生态中游刃有余地构建出体验卓越的图片类应用。现在,就请将这些知识付诸实践,创造出让用户眼前一亮的视觉体验吧!

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐