如何将RGB格式的文件转换成图片显示
==================

#### 问题现象

HarmonyOS中视频流格式转换成的RGB格式的图像文件，如何以图片的形式展示？

#### 背景知识

[PixelMap](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-sendableimage#pixelmap)是图像解码后的一种无压缩位图格式，图片解码是指将所支持格式的图片文件解码成统一的PixelMap格式，目前支持的图片格式有JPEG、PNG、GIF、WebP、BMP、SVG、ICO、DNG、HEIF。PixelMap主要用于图像显示或进一步处理，这种格式可以有效地存储图像的原始数据，使其可以方便地进行[图像变换](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/image-transformation)，如裁剪、缩放、偏移、旋转、翻转、设置透明度等。

RGB文件是指使用RGB（红、绿、蓝）颜色模式存储图像数据的任何文件，这种模式主要用于显示设备，是基于光的三原色模型。

#### 解决方案

RGB格式的文件无法直接用Image组件显示，需要使用RGB格式的文件中的数据来创建PixelMap，再使用Image组件来显示，步骤如下：

1.  读取RGB格式的文件中的数据。
2.  图像数据存入到ArrayBuffer中。
3.  设置创建像素的属性，包括透明度、尺寸、缩略值、像素格式和是否可编辑。
4.  通过图像像素数据和像素的属性[image.createPixelMap](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-image-f#imagecreatepixelmap8-1)创建PixelMap。
5.  使用Image组件显示创建的PixelMap。
    
    import { resourceManager } from '@kit.LocalizationKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { image } from '@kit.ImageKit';
    import { common } from '@kit.AbilityKit';
    
    @Entry
    @Component
    struct Index {
      @State pixelMap: image.PixelMap | null \= null;
      context: Context \= this.getUIContext().getHostContext() as common.UIAbilityContext;
      resourceMgr: resourceManager.ResourceManager \= this.context.resourceManager;
      openRGB(file: string) {
      _  // 1、读取RGB格式的文件_
        this.resourceMgr.getRawFileContent(file).then((fileData: Uint8Array) \=\> {
         _ // 2、获取到文件的数据，存储成ArrayBuffer_
          const buffer \= fileData.buffer.slice(0);
          console.info(\`buffer.bytelength:${buffer.byteLength}\`);
       _   // 3、设置创建PixelMap的配置，srcPixelFormat是原数据的格式（即RGB文件的格式），pixelFormat是创建出来的PixelMap格式，size是分辨率_
          let opts: image.InitializationOptions \= {
            editable: true,
            srcPixelFormat: 4,
            pixelFormat: 3,
            size: { height: 1080, width: 1920 }
          };
        _  // 4、创建PixelMap_
          image.createPixelMap(buffer, opts).then((pixelMap: image.PixelMap) \=\> {
            this.pixelMap \= pixelMap;
            console.info('Succeeded in creating pixelmap.');
          }).catch((error: BusinessError) \=\> {
            console.error(\`Failed to create pixelmap. code is ${error.code}, message is ${error.message}\`);
          });
        }).catch((err: BusinessError) \=\> {
          console.error(\`Failed to get RawFileContent,error code:${err.code}\`);
        });
      }
      build() {
        RelativeContainer() {
          Column() {
           _ // 示例文件仅作参考，实际开发请以本地文件为准_
            Button('打开RGB').onClick(() \=\> {
              this.openRGB('imageData.rgb');
            })
      _      // 5、将PixelMap通过Image组件显示出来_
            Image(this.pixelMap).objectFit(ImageFit.Contain);
          }
        }
        .height('100%')
        .width('100%')
      }
    }
    

#### 常见FAQ

Q：使用BGRA8888的格式创建PixelMap后，将其B和R颜色通道数据互换为RGBA8888格式后打印的像素格式应该为更换后的RGBA8888但仍为BGRA8888。

A：图像的像素数据储存在buffer中，创建PixelMap设置PixelMapFormat时就是指定以什么方式去解析读取像素数据。手动更改buffer里面的数据后没有改变PixelMap去解析buffer的方式，所以仍然是原本的格式，需要重新更改PixelMapFormat去读取数据。