1# 如何转换图片格式 2 3## 场景说明 4当我们获取到图片或者视频的缩略图后,返回的是pixelMap,此时有开发者会有疑问如何将pixelMap转换成jpeg等其他格式的图片,其实使用image类中的packing方法就可以将pixelMap重新打包成新的格式(当前只支持jpeg,webp格式),再使用文件管理就可以将图片存入到应用的沙箱路径。本例即为大家介绍如何完成图片格式转换。 5 6## 运行环境 7本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发: 8 9- IDE: DevEco Studio 4.0 Beta1 10- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1) 11 12## 效果呈现 13本例最终实现效果为:将工程资源文件中png格式的图片转换为jpg格式,并保存在设备中。由于本例不涉及UI讲解,所以不在此提供UI效果。 14 15## 实现思路 16本例中完成图片格式转换包含三个关键步骤,相关步骤及实现方案如下: 17- 获取到要转换图片的PixelMap数据:使用image的createPixelMap方法获取到图片的PixelMap数据。 18- 将图片的PixelMap重新打包转换为其他格式:使用packing方法进行打包,打包时可以设置格式、压缩质量等。 19- 将重新打包好的图片保存到应用目录:使用图库选择器photoViewPicker的相关功能以及file读写操作完成图片的保存。 20 21## 开发步骤 22由于本例重点讲解图片格式的转换,所以开发步骤会着重讲解相关实现,不相关的内容不做介绍,全量代码可参考完整代码章节。 231. 获取要转换图片的PixelMap数据。 24 25 先通过上下文context获取到资源管理器resourceManager,然后通过资源管理器获取到图片数据,然后获取图片的ArrayBuffer,最后通过ArrayBuffer创建imageSource,获取到pixelMap,完成图片解码。 26 27 具体代码如下: 28 ```ts 29 import common from '@ohos.app.ability.common'; 30 31 @Entry 32 @Component 33 struct Index { 34 ... 35 context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext 36 ... 37 38 async getPixelMap(){ 39 // 获取resourceManager资源管理 40 const resourceMgr = this.context.resourceManager 41 // 获取rawfile文件夹下imagetransfer.PNG的ArrayBuffer 42 const fileData = await resourceMgr.getMediaContent($r('app.media.imagetransfer')) 43 const buffer = fileData.buffer 44 // 创建imageSource 45 const imageSource = image.createImageSource(buffer) 46 // 获取PixelMap 47 const pixelMap = await imageSource.createPixelMap() 48 return pixelMap 49 } 50 ... 51 } 52 ``` 532. 将图片的PixelMap重新打包转换为其他格式。 54 55 先通过createImagePacker构建ImagePacker实例,再通过该实例调用packing方法进行打包,打包时传入获取到的PixelMap数据及重新打包的图片格式等相关配置信息。 56 具体代码如下: 57 ```ts 58 ... 59 @State src:PixelMap = undefined 60 ... 61 // 页面加载前将获取到的图片PixelMap数据赋值给状态变量src 62 async aboutToAppear() { 63 this.src = await this.getPixelMap() 64 } 65 ... 66 // 创建ImagePacker实例 67 let imagePackerApi = image.createImagePacker(); 68 let options = { 69 // 设置重新打包的图片格式 70 format: 'image/jpeg', 71 quality: 98 72 }; 73 // 打包时传入图片的PixelMap:src和图片打包选项:option,异步获取打包后的数据data 74 imagePackerApi.packing(this.src, options).then((data) => { 75 console.log('Succeeded in packing the image.'); 76 }).catch(error => { 77 console.log('Failed to pack the image..'); 78 .... 79 }) 80 ``` 813. 将重新打包好的图片保存到应用目录。 82 83 使用图库选择器photoViewPicker保存文件,保存时可以在保存界面选择保存路径并设定文件名。此时保存的是空文件,然后再使用file将重新打包的图片数据写入保存的文件中,保存完成后我们便可以在保存路径下找到转换格式后的图片文件了。 84 具体代码如下: 85 ```ts 86 ... 87 // 打包时传入图片的pixelmap:src和图片打包选项:option,异步获取打包后的数据data 88 imagePackerApi.packing(this.src, options).then((data) => { 89 // 创建文件管理器保存选项实例 90 let photoSaveOptions = new picker.PhotoSaveOptions(); 91 // 保存文件名(可选) 92 photoSaveOptions.newFileNames = ["imageTransfer.jpg"]; 93 let photoViewPicker = new picker.PhotoViewPicker(); 94 95 // 保存时传入保存的文件名:photoSaveOptions 96 photoViewPicker.save(photoSaveOptions) 97 .then((photoSaveResult) => { 98 setTimeout(() => { 99 // 获取到保存文件的URI,后续进行文件读取等操作 100 this.uri = photoSaveResult[0]; 101 102 fs.open(this.uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).then((file) => { 103 // 将图片打包数据data写入保存的文件 104 fs.write(file.fd, data).then((number) => { 105 console.info("foo imagetest: write data to file succeed and size is:" + number); 106 }).catch((err) => { 107 console.info("foo imagetest: write data to file failed with error:" + err); 108 }); 109 // 完成文件写入后,关闭文件 110 fs.close(file, (err) => { 111 if (err) { 112 console.info("close file failed with error message: " + err.message + ", error code: " + err.code); 113 } else { 114 console.info("close file success"); 115 } 116 }); 117 }).catch((err) => { 118 console.info("foo open file failed with error message: " + err.message + ", error code: " + err.code); 119 }); 120 121 }, 200) 122 123 }) 124 .catch((err) => { 125 console.error('PhotoViewPicker.save failed with err: ' + err); 126 }) 127 }) 128 ... 129 ``` 130## 完整代码 131本例完整代码如下: 132```ts 133import image from '@ohos.multimedia.image'; 134import fs from '@ohos.file.fs'; 135import common from '@ohos.app.ability.common'; 136import picker from '@ohos.file.picker'; 137 138@Entry 139@Component 140struct Index { 141 @State src:PixelMap = undefined 142 context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext 143 private uri = null 144 // 页面加载前将获取到的图片PixelMap数据赋值给状态变量src 145 async aboutToAppear() { 146 this.src = await this.getPixelMap() 147 } 148 149 async getPixelMap(){ 150 // 获取resourceManager资源管理 151 const resourceMgr = this.context.resourceManager 152 // 获取rawfile文件夹下httpimage.PNG的ArrayBuffer 153 const fileData = await resourceMgr.getMediaContent($r('app.media.contact6')) 154 const buffer = fileData.buffer 155 // 创建imageSource 156 const imageSource = image.createImageSource(buffer) 157 // 创建PixelMap 158 const pixelMap = await imageSource.createPixelMap() 159 return pixelMap 160 console.log('pixelMap ' + JSON.stringify(this.src.getPixelBytesNumber())) 161 } 162 163 build() { 164 Row() { 165 Column() { 166 Button('转换图片格式:png->jpeg') 167 .onClick(() => { 168 // 创建ImagePacker实例 169 let imagePackerApi = image.createImagePacker(); 170 // 设置重新打包的图片格式,及图片压缩质量 171 let options = { 172 format: 'image/jpeg', 173 quality: 98 174 }; 175 // 打包时传入图片的pixelmap:src和图片打包选项:option,异步获取打包后的数据data 176 imagePackerApi.packing(this.src, options).then((data) => { 177 // 创建文件管理器保存选项实例 178 let photoSaveOptions = new picker.PhotoSaveOptions(); 179 // 保存文件名(可选) 180 photoSaveOptions.newFileNames = ["imageTransfer.jpg"]; 181 let photoViewPicker = new picker.PhotoViewPicker(); 182 // 保存时传入保存的文件名:photoSaveOptions 183 photoViewPicker.save(photoSaveOptions) 184 .then((photoSaveResult) => { 185 console.log('foo start') 186 setTimeout(() => { 187 // 获取到图片的URI后进行文件读取等操作 188 this.uri = photoSaveResult[0]; 189 fs.open(this.uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE).then((file) => { 190 // 将图片打包数据data写入保存的文件 191 fs.write(file.fd, data).then((number) => { 192 console.info("foo imagetest: write data to file succeed and size is:" + number); 193 }).catch((err) => { 194 console.info("foo imagetest: write data to file failed with error:" + err); 195 }); 196 // 完成文件写入后,关闭文件 197 fs.close(file, (err) => { 198 if (err) { 199 console.info("close file failed with error message: " + err.message + ", error code: " + err.code); 200 } else { 201 console.info("close file success"); 202 } 203 }); 204 }).catch((err) => { 205 console.info("foo open file failed with error message: " + err.message + ", error code: " + err.code); 206 }); 207 }, 200) 208 }) 209 .catch((err) => { 210 console.error('PhotoViewPicker.save failed with err: ' + err); 211 }) 212 }) 213 }) 214 } 215 .width('100%') 216 } 217 .height('100%') 218 } 219} 220``` 221 222## 参考 223- [@ohos.multimedia.image (图片处理)](../application-dev/reference/apis-image-kit/js-apis-image.md) 224- [@ohos.file.fs (文件管理)](../application-dev/reference/apis-core-file-kit/js-apis-file-fs.md) 225- [@ohos.file.picker (选择器)](../application-dev/reference/apis-core-file-kit/js-apis-file-picker.md)