HarmonyOS 读取PixelMap的ArrayBuffer,再使用读取的数据创建PixelMap展示,图片变成了黑白,丢失了颜色。?

读取PixelMap的ArrayBuffer,再使用读取的数据创建PixelMap,图片变成了黑白,丢失了颜色。

1、读取PixelMap的ArrayBuffer:

async pixelMapToArray(pixelMap:PixelMap){
  //size为需要创建的像素buffer大小,取值为:height * width *4
  let size = pixelMap.getPixelBytesNumber();
  const readBuffer: ArrayBuffer = new ArrayBuffer(size);
  if (pixelMap) {
    await pixelMap.readPixelsToBuffer(readBuffer);
    let bufferSize = readBuffer.byteLength;
    return readBuffer;
  }
  return readBuffer;
}

2、使用读取的数据创建PixelMap:

arrayToPixelMap(readBuffer: ArrayBuffer | null, w:number, h:number, callback:(pixelMap:PixelMap)=>void){
  let opts: image.InitializationOptions = { editable: true, pixelFormat: image.PixelMapFormat.RGBA_8888,
    size: { height: h, width: w } }
  image.createPixelMap(readBuffer, opts).then((pixelMap)=>{
    callback(pixelMap);
  });
}

3、调用:

PhotoChangeUtils.pixelMapToArray(pixelMap).then((buffer)=>{
  let imageInfo = pixelMap.getImageInfoSync();
  let w = imageInfo.size.width;
  let h = imageInfo.size.height;
  PhotoChangeUtils.arrayToPixelMap(buffer, w, h, (pixelMap)=>{
    this.livePixelMap = pixelMap;
  } )
})
阅读 480
1 个回答

由image.createPixelMap描述可知通过属性创建PixelMap,默认采用BGRA\_8888格式处理数据,通过Promise返回结果,即使创建pixelMap时的buffer和options都是rgba格式的,当前接口只能处理BGRA流,建议尝试统一更改为BGRA\_8888。

参考示例:

import { image } from '@kit.ImageKit';
import fs from '@ohos.file.fs';
class JoinPicture {
  /**
   * RGBA与BGRA编码互换,前后统一编码后,就不需要转换了
   * @param data
   * @returns
   */
  rgba2BGRA(data: ArrayBuffer): ArrayBuffer {
    let length: number = data.byteLength;
    let tempBuffer: ArrayBuffer = new ArrayBuffer(length);
    let rgbaData = new DataView(data);
    let bgraData = new DataView(tempBuffer);
    for (let i = 0; i < length; i += 4) {
      bgraData.setUint8(i, rgbaData.getUint8(i + 2));
      bgraData.setUint8(i + 1, rgbaData.getUint8(i + 1));
      bgraData.setUint8(i + 2, rgbaData.getUint8(i));
      bgraData.setUint8(i + 3, rgbaData.getUint8(i + 3));
    }
    return bgraData.buffer
  }

  //1、读取PixelMap的ArrayBuffer
  async pixelMapToArray(pixelMap:PixelMap){
    //size为需要创建的像素buffer大小,取值为:height * width *4
    let size = pixelMap.getPixelBytesNumber();
    const readBuffer: ArrayBuffer = new ArrayBuffer(size);
    if (pixelMap) {
      await pixelMap.readPixelsToBuffer(readBuffer);
      let bufferSize = readBuffer.byteLength;
      return readBuffer;
    }
    return readBuffer;
  }

  //2、使用读取的数据创建PixelMap
  arrayToPixelMap(readBuffer: ArrayBuffer | null, w:number, h:number, callback:(pixelMap:PixelMap)=>void){
    let opts: image.InitializationOptions = { editable: true, pixelFormat: image.PixelMapFormat.BGRA_8888,
      size: { height: h, width: w } }
    image.createPixelMap(readBuffer, opts).then((pixelMap)=>{
      callback(pixelMap);
    });
  }

  // 这里只考虑横向排列拼接,且每张小图的高度一致
  async join(picturePaths: Array<string>, joinPath: string, callback: Function) {
    try {
      if (picturePaths.length < 2) {
        console.info('PictureJoinTogether 需要拼接的图片数量不足')
        return;
      }
      const tempPath = picturePaths[0];
      const imageSource = image.createImageSource(tempPath);
      const imageInfo = await imageSource.getImageInfo();
      const singleWidth = imageInfo.size.width;
      const singleHeight = imageInfo.size.height;
      const combineOpts: image.InitializationOptions = {
        alphaType: 0,
        editable: true,
        // 注意上下格式统一
        pixelFormat: image.PixelMapFormat.BGRA_8888,
        size: { width: singleWidth * picturePaths.length, height: singleHeight }
      }
      const singleOpts: image.DecodingOptions = {
        editable: true,
        desiredPixelFormat: image.PixelMapFormat.BGRA_8888,
        desiredSize: { width: singleWidth, height: singleHeight }
      };
      const combineColor = new ArrayBuffer(combineOpts.size.width * combineOpts.size.height * 4);
      let singleColor = new ArrayBuffer(singleOpts.desiredSize!.width * singleOpts.desiredSize!.height * 4);
      const newPixelMap = await image.createPixelMap(combineColor, combineOpts);
      let newPixelMap2 =newPixelMap;
      this.pixelMapToArray(newPixelMap).then((buffer)=>{
        let imageInfo = newPixelMap.getImageInfoSync();
        let w = imageInfo.size.width;
        let h = imageInfo.size.height;
        this.arrayToPixelMap(buffer, w, h, (pixelMaps)=>{
          newPixelMap2 = pixelMaps;
        } )
      })

      for (let x = 0; x < picturePaths.length; x++) {
        //读取小图
        //图片应用沙箱路径
        let singlePath = picturePaths[x];
        let imageSource = image.createImageSource(singlePath);
        const singlePixelMap = await imageSource.createPixelMap(singleOpts);
        await singlePixelMap.readPixelsToBuffer(singleColor);
        //写入大图
        let area: image.PositionArea = {
          pixels: singleColor,
          offset: 0,
          stride: singleWidth * 4,
          region: {
            size: { height: singleHeight, width: singleWidth },
            x: singleWidth * x,
            y: 0
          }
        }
        await newPixelMap2.writePixels(area);
      }
      let combinePixelMap = newPixelMap2;
      //保存大图
      const saveResult = await this.save(combinePixelMap, joinPath)
      saveResult && callback();
    } catch (err) {
      console.error('PictureJoinTogether join error: ' + JSON.stringify(err))
    }
  }

  async save(pixelMap: image.PixelMap | undefined, path: string) {
    if (pixelMap === undefined) {
      return false;
    }
    const imagePackerApi: image.ImagePacker = image.createImagePacker();
    let packOpts: image.PackingOption = { format: "image/jpeg", quality: 100 };
    const packingArrayBuffer = await imagePackerApi.packing(pixelMap, packOpts);
    console.info('packing succeeded.');
    let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
    fs.writeSync(file.fd, packingArrayBuffer, { offset: 0 })
    fs.closeSync(file.fd)
    return true
  }
}
export const joinPicture = new JoinPicture()
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
HarmonyOS
子站问答
访问
宣传栏