OpenHarmony开发者论坛

标题: 图片格式转换 [打印本页]

作者: 一只杨    时间: 2023-9-4 11:35
标题: 图片格式转换

【问题描述】
当我们获取到图片或者视频的缩略图后,返回的是pixelMap,如何将pixelMap转换成jpeg等其他格式的图片呢。

【运行环境】
IDE: DevEco Studio 4.0 Beta1
SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)



作者: 马迪    时间: 2023-9-5 10:50
完成图片格式转换包含三个关键步骤,相关步骤及实现方案如下:
- 获取到要转换图片的PixelMap数据:使用image的createPixelMap方法获取到图片的PixelMap数据。
- 将图片的PixelMap重新打包转换为其他格式:使用packing方法进行打包,打包时可以设置格式、压缩质量等。
- 将重新打包好的图片保存到应用目录:使用图库选择器photoViewPicker的相关功能以及file读写操作完成图片的保存。

## 开发步骤
由于本例重点讲解图片格式的转换,所以开发步骤会着重讲解相关实现,不相关的内容不做介绍,全量代码可参考完整代码章节。
1. 获取要转换图片的PixelMap数据。

    先通过上下文context获取到资源管理器resourceManager,然后通过资源管理器获取到图片数据,然后获取图片的ArrayBuffer,最后通过ArrayBuffer创建imageSource,获取到pixelMap,完成图片解码。

    具体代码如下:
  1. import common from '@ohos.app.ability.common';

  2.     @Entry
  3.     @Component
  4.     struct Index {
  5.       ...
  6.       context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext
  7.       ...

  8.       async getPixelMap(){
  9.         // 获取resourceManager资源管理
  10.         const resourceMgr = this.context.resourceManager
  11.         // 获取rawfile文件夹下imagetransfer.PNG的ArrayBuffer
  12.         const fileData = await resourceMgr.getMediaContent($r('app.media.imagetransfer'))
  13.         const buffer = fileData.buffer
  14.         // 创建imageSource
  15.         const imageSource = image.createImageSource(buffer)
  16.         // 获取PixelMap
  17.         const pixelMap = await imageSource.createPixelMap()
  18.         return pixelMap
  19.       }
  20.       ...
  21.     }
复制代码

2. 将图片的PixelMap重新打包转换为其他格式。

    先通过createImagePacker构建ImagePacker实例,再通过该实例调用packing方法进行打包,打包时传入获取到的PixelMap数据及重新打包的图片格式等相关配置信息。
    具体代码如下:

  1. ...
  2.     @State src:PixelMap = undefined
  3.     ...
  4.     // 页面加载前将获取到的图片PixelMap数据赋值给状态变量src
  5.     async aboutToAppear() {
  6.       this.src = await this.getPixelMap()
  7.     }
  8.     ...
  9.     // 创建ImagePacker实例
  10.     let imagePackerApi = image.createImagePacker();
  11.     let options = {
  12.       // 设置重新打包的图片格式
  13.       format: 'image/jpeg',
  14.       quality: 98
  15.     };
  16.     // 打包时传入图片的PixelMap:src和图片打包选项:option,异步获取打包后的数据data
  17.     imagePackerApi.packing(this.src, options).then((data) => {
  18.       console.log('Succeeded in packing the image.');
  19.       }).catch(error => {
  20.       console.log('Failed to pack the image..');
  21.       ....
  22.     })
复制代码

3. 将重新打包好的图片保存到应用目录。

    使用图库选择器photoViewPicker保存文件,保存时可以在保存界面选择保存路径并设定文件名。此时保存的是空文件,然后再使用file将重新打包的图片数据写入保存的文件中,保存完成后我们便可以在保存路径下找到转换格式后的图片文件了。
    具体代码如下:
  1. ...
  2.     // 打包时传入图片的pixelmap:src和图片打包选项:option,异步获取打包后的数据data
  3.     imagePackerApi.packing(this.src, options).then((data) => {
  4.       // 创建文件管理器保存选项实例
  5.       let photoSaveOptions = new picker.PhotoSaveOptions();
  6.       // 保存文件名(可选)
  7.       photoSaveOptions.newFileNames = ["imageTransfer.jpg"];
  8.       let photoViewPicker = new picker.PhotoViewPicker();

  9.       // 保存时传入保存的文件名:photoSaveOptions
  10.       photoViewPicker.save(photoSaveOptions)
  11.         .then((photoSaveResult) => {
  12.           setTimeout(() => {
  13.             // 获取到保存文件的URI,后续进行文件读取等操作
  14.             this.uri = photoSaveResult[0];

  15.             fs.open(this.uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).then((file) => {
  16.               // 将图片打包数据data写入保存的文件
  17.               fs.write(file.fd, data).then((number) => {
  18.                 console.info("foo imagetest: write data to file succeed and size is:" + number);
  19.               }).catch((err) => {
  20.                 console.info("foo imagetest: write data to file failed with error:" + err);
  21.               });
  22.               // 完成文件写入后,关闭文件
  23.               fs.close(file, (err) => {
  24.                 if (err) {
  25.                   console.info("close file failed with error message: " + err.message + ", error code: " + err.code);
  26.                 } else {
  27.                   console.info("close file success");
  28.                 }
  29.               });
  30.             }).catch((err) => {
  31.               console.info("foo open file failed with error message: " + err.message + ", error code: " + err.code);
  32.             });

  33.           }, 200)

  34.         })
  35.         .catch((err) => {
  36.           console.error('PhotoViewPicker.save failed with err: ' + err);
  37.         })
  38.     })
  39.     ...
复制代码

完整代码请参考:
  1. import image from '@ohos.multimedia.image';
  2. import fs from '@ohos.file.fs';
  3. import common from '@ohos.app.ability.common';
  4. import picker from '@ohos.file.picker';

  5. @Entry
  6. @Component
  7. struct Index {
  8.   @State src:PixelMap = undefined
  9.   context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext
  10.   private  uri = null
  11.   // 页面加载前将获取到的图片PixelMap数据赋值给状态变量src
  12.   async aboutToAppear() {
  13.     this.src = await this.getPixelMap()
  14.   }

  15.   async getPixelMap(){
  16.     // 获取resourceManager资源管理
  17.     const resourceMgr = this.context.resourceManager
  18.     // 获取rawfile文件夹下httpimage.PNG的ArrayBuffer
  19.     const fileData = await resourceMgr.getMediaContent($r('app.media.contact6'))
  20.     const buffer = fileData.buffer
  21.     // 创建imageSource
  22.     const imageSource = image.createImageSource(buffer)
  23.     // 创建PixelMap
  24.     const pixelMap = await imageSource.createPixelMap()
  25.     return pixelMap
  26.     console.log('pixelMap  ' + JSON.stringify(this.src.getPixelBytesNumber()))
  27.   }

  28.   build() {
  29.     Row() {
  30.       Column() {
  31.         Button('转换图片格式:png->jpeg')
  32.           .onClick(() => {
  33.             // 创建ImagePacker实例
  34.             let imagePackerApi = image.createImagePacker();
  35.             // 设置重新打包的图片格式,及图片压缩质量
  36.             let options = {
  37.               format: 'image/jpeg',
  38.               quality: 98
  39.             };
  40.             // 打包时传入图片的pixelmap:src和图片打包选项:option,异步获取打包后的数据data
  41.             imagePackerApi.packing(this.src, options).then((data) => {
  42.               // 创建文件管理器保存选项实例
  43.               let photoSaveOptions = new picker.PhotoSaveOptions();
  44.               // 保存文件名(可选)
  45.               photoSaveOptions.newFileNames = ["imageTransfer.jpg"];
  46.               let photoViewPicker = new picker.PhotoViewPicker();
  47.               // 保存时传入保存的文件名:photoSaveOptions
  48.               photoViewPicker.save(photoSaveOptions)
  49.                 .then((photoSaveResult) => {
  50.                   console.log('foo start')
  51.                   setTimeout(() => {
  52.                     // 获取到图片的URI后进行文件读取等操作
  53.                     this.uri = photoSaveResult[0];
  54.                     fs.open(this.uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).then((file) => {
  55.                       // 将图片打包数据data写入保存的文件
  56.                       fs.write(file.fd, data).then((number) => {
  57.                         console.info("foo imagetest: write data to file succeed and size is:" + number);
  58.                       }).catch((err) => {
  59.                         console.info("foo imagetest: write data to file failed with error:" + err);
  60.                       });
  61.                       // 完成文件写入后,关闭文件
  62.                       fs.close(file, (err) => {
  63.                         if (err) {
  64.                           console.info("close file failed with error message: " + err.message + ", error code: " + err.code);
  65.                         } else {
  66.                           console.info("close file success");
  67.                         }
  68.                       });
  69.                     }).catch((err) => {
  70.                       console.info("foo open file failed with error message: " + err.message + ", error code: " + err.code);
  71.                     });
  72.                   }, 200)
  73.                 })
  74.                 .catch((err) => {
  75.                   console.error('PhotoViewPicker.save failed with err: ' + err);
  76.                 })
  77.             })
  78.           })
  79.       }
  80.       .width('100%')
  81.     }
  82.     .height('100%')
  83.   }
  84. }
复制代码


参考内容:
@ohos.multimedia.image (图片处理)
@ohos.file.fs (文件管理)
@ohos.file.picker (选择器)






欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5