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;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

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);
  });
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

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;
  } )
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
HarmonyOS
2024-12-23 15:02:46
849浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
aquaa

由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()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
分享
微博
QQ
微信
回复
2024-12-23 19:29:53
相关问题
可以以颜色创建pixelmap
889浏览 • 1回复 待解决
HarmonyOS pixelMap转成ArrayBuffer
1200浏览 • 1回复 待解决
HarmonyOS 怎么改pixelmap颜色
587浏览 • 1回复 待解决
HarmonyOS PixelMap加载图片
719浏览 • 1回复 待解决