如何将一张图片写入到另一张图片中
================

#### 问题现象

在图片开发过程中，如何将图片写入另一张背景图片中，且背景图片需要大于原图片大小？

需要写入的图片：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/1f/v3/yDhxwNyGS2Ol6K_XM9BxnA/zh-cn_image_0000002658791871.png?HW-CC-KV=V1&HW-CC-Date=20260709T134239Z&HW-CC-Expire=86400&HW-CC-Sign=2A6D4775571D1A12C5A8C1396A54F6471C9B41BF2A495285AAEECE3FD9FA2491 "点击放大")

#### 背景知识

*   [Image](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-image)：Image为图片组件，常用于在应用中显示图片。Image支持加载PixelMap、ResourceStr和DrawableDescriptor类型的数据源，支持png、jpg、jpeg、bmp、svg、webp、gif和heif类型的图片格式。
*   [@ohos.multimedia.image (图片处理)](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-image)：提供图片解码、图片编码、图片编辑和处理、图片接收等能力，包括创建PixelMap、读取图像像素数据、读取区域内的图片数据等。
*   [readPixelsSync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-pixelmap#readpixelssync12)：固定按照BGRA\_8888格式，读取PixelMap指定区域内的图像像素数据，并写入PositionArea.pixels缓冲区中，该区域由PositionArea.region指定，同步返回结果。
*   [readPixelsToBufferSync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-pixelmap#readpixelstobuffersync12)：按照PixelMap的像素格式，读取PixelMap的图像像素数据，并写入缓冲区中，同步返回结果。
*   [writePixelsSync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-pixelmap#writepixelssync12)：固定按照BGRA\_8888格式，读取PositionArea.pixels缓冲区中的图像像素数据，并写入PixelMap指定区域内，该区域由PositionArea.region指定，同步返回结果。

#### 解决方案

创建指定格式的PixelMap。用readPixelsSync方法，固定按照BGRA\_8888格式，读取PixelMap指定区域内的图像像素数据，并写入PositionArea.pixels缓冲区中。再用writePixelsSync方法，固定按照BGRA\_8888格式，读取PositionArea.pixels缓冲区中的图像像素数据，并写入PixelMap指定区域内。

import { image } from '@kit.ImageKit';
import { resourceManager } from '@kit.LocalizationKit';
import { common } from '@kit.AbilityKit';

@Entry
@Component
struct PassImage {
  @State imagePix: image.PixelMap | null = null;
  arr: ArrayBuffer | null = null;

  aboutToAppear(): void {
    let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  _  // 获取resourceManager资源管理器_
    const resourceMgr: resourceManager.ResourceManager = context.resourceManager;
    let fd = resourceMgr.getRawFdSync('picture.jpg');
    let source = image.createImageSource(fd);
    let imPix = source.createPixelMapSync();
    let imInfo = imPix.getImageInfoSync();
    this.imagePix = imPix;
   _ // 创建像素数据_
    _// 下述width、height加1k创建比原图更大的像素区域模拟写入另一张图片中，实际情况请以需要写入的图片宽高为准_
    const width = imInfo.size.width + 1000;
    const height = imInfo.size.height + 1000;
    const bytesPerPixel = 4;
    const bufferSize = width \* height \* bytesPerPixel;
    const colorBuffer = new ArrayBuffer(bufferSize);
 _   // 创建PixelMap_
    const bufferArr = new Uint8Array(colorBuffer);
  _  // 填充背景色_
    for (let i = 0; i < bufferArr.length; i += bytesPerPixel) {
      bufferArr\[i\] = 0xF5; _// B通道（原R通道）_
      bufferArr\[i+1\] = 0xF3; _// G通道_
      bufferArr\[i+2\] = 0xF1; _// R通道（原B通道）_
      bufferArr\[i+3\] = 0xFF; _// Alpha通道_
    }
    const opts: image.InitializationOptions = {
      editable: true,
      pixelFormat: image.PixelMapFormat.BGRA\_8888,
      size: { width, height }
    };
    this.imagePix = image.createPixelMapSync(colorBuffer, opts);
    let pixelBytesNumber: number = imPix.getPixelBytesNumber();
    const readBuffer = new ArrayBuffer(pixelBytesNumber);
    const area: image.PositionArea = {
      pixels: readBuffer, _// 源图片的像素数据_
      offset: 0, _// 数据起始偏移量_
      stride: imInfo.size.width \* 4, _// 每行字节数（源图片宽度\*4）_
      region: {
        size: { width: imInfo.size.width, height: imInfo.size.height }, _// 写入区域尺寸（源图片尺寸）_
        x: 0, _// 目标位置x坐标_
        y: 0 _// 目标位置y坐标_
      }
    };
   _ // 写入缓存区使用下列方法，固定按照BGRA\_8888格式，读取PixelMap指定区域内的图像像素数据，并写入PositionArea.pixels缓冲区中_
    imPix.readPixelsSync(area);
  _  // 固定按照BGRA\_8888格式，读取PositionArea.pixels缓冲区中的图像像素数据，并写入PixelMap指定区域内_
    this.imagePix.writePixelsSync(area);
    resourceMgr.closeRawFd('picture.jpg');
  }

  build() {
    Column() {
      Image(this.imagePix).width('100%').objectFit(ImageFit.Auto)
    }.width('100%').height('100%')
  }
}

#### 常见FAQ

Q：其他平台中bitmap.setPixels对应HarmonyOS是什么实现方式？

A：其他平台中bitmap.setPixels方法可以使用[writePixels](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-pixelmap#writepixels7)方法实现。