1# 编辑图片 2 3## 场景说明 4图片编辑是在应用中经常用到的功能,比如相机拍完照片后可以对照片进行编辑;截图后可以对截图进行编辑;可以对图库中的图片进行编辑等。本例即为大家介绍如何获取图片的pixelMap数据,并通过pixelMap对图片进行常见的编辑操作。 5 6## 效果呈现 7本例最终效果如下: 8 9![image-edit](figures/image-edit.gif) 10 11## 运行环境 12本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发: 13 14- IDE: DevEco Studio 3.1 Release 15- SDK: Ohos_sdk_public 3.2.12.5(API Version 9 Release) 16 17## 实现思路 18本例中展示的是对资源文件中的图片进行编辑,编辑操作主要分为以下三步: 191. 对图片解码,获取到pixelMap:先通过上下文context获取到资源管理器resourceManager,然后通过资源管理器获取到图片数据,然后获取图片的ArrayBuffer,最后通过ArrayBuffer创建imageSource,获取到pixelMap,完成图片解码。 202. 编辑pixelMap:获取到pixelMap后就可以针对pixelMap进行裁剪、缩放、偏移、旋转、翻转、调节透明度等操作。 213. 将编辑好的pixelMap渲染显示出来:完成对pixelMap的编辑后,可以通过Image组件将编辑后的pixelMap渲染显示出来。 22 23## 开发步骤 24由于本例重点讲解图片编辑,所以开发步骤会着重讲解相关实现,不相关的内容不做介绍,全量代码可参考完整代码章节。 251. 对图片进行解码。 26 27 先通过上下文context获取到资源管理器resourceManager,然后通过资源管理器获取到图片数据,然后获取图片的ArrayBuffer,最后通过ArrayBuffer创建imageSource,获取到pixelMap,完成图片解码。 28 具体代码如下: 29 ```ts 30 async get_pixelmap(){ 31 // 获取resourceManager资源管理 32 const context = getContext(this) 33 const resourceMgr = context.resourceManager 34 // 获取rawfile文件夹下httpimage.PNG的ArrayBuffer 35 const fileData = await resourceMgr.getMediaContent($r('app.media.httpimage')) 36 const buffer = fileData.buffer 37 // 创建imageSource 38 const imageSource = image.createImageSource(buffer) 39 // 创建PixelMap 40 const pixelMap = await imageSource.createPixelMap() 41 return pixelMap 42 } 43 ``` 442. 编辑pixelMap。 45 46 分别通过以下方法对pixelMap进行裁剪、缩放、偏移、旋转、翻转、调节透明度等操作:crop、scale、translate、rotate、flip、opacity。 47 具体代码如下: 48 ```ts 49 // 对pixelMap进行裁剪 50 async crop_image(){ 51 let pixelMap = await this.get_pixelmap() 52 pixelMap.crop({x:0,y:0,size:{height:300,width:300}}) 53 this.imagePixelMap = pixelMap 54 } 55 // 对pixelMap进行缩放 56 async scale_image(){ 57 let pixelMap = await this.get_pixelmap() 58 pixelMap.scale(0.5,0.5) 59 this.imagePixelMap = pixelMap 60 } 61 // 对pixelMap进行偏移 62 async translate_image(){ 63 let pixelMap = await this.get_pixelmap() 64 pixelMap.translate(100,100); 65 this.imagePixelMap = pixelMap 66 } 67 // 对pixelMap进行旋转 68 async rotate_image(){ 69 let pixelMap = await this.get_pixelmap() 70 pixelMap.rotate(90); 71 this.imagePixelMap = pixelMap 72 } 73 // 对pixelMap进行翻转 74 async flip_image(){ 75 let pixelMap = await this.get_pixelmap() 76 pixelMap.flip(false, true); 77 this.imagePixelMap = pixelMap 78 } 79 // 对pixelMap进行透明度调整 80 async opacity_image(){ 81 let pixelMap = await this.get_pixelmap() 82 pixelMap.opacity(0.5); 83 this.imagePixelMap = pixelMap 84 } 85 ``` 863. 通过Image组件将编辑后的pixelMap渲染显示出来。 87 88 第2步中将编辑好的pixelMap传递给状态变量imagePixelMap,本步中直接将imagePixelMap传入Image组件进行渲染显示。 89 具体代码如下: 90 ```ts 91 if(!this.edit){ 92 Row(){ 93 Image($r('app.media.httpimage')).objectFit(ImageFit.None) 94 }.width('100%').height('50%').backgroundColor('#F0F0F0') 95 }else{ 96 Row(){ 97 // 将编辑好的pixelMap传递给状态变量imagePixelMap后,通过Image组件进行渲染 98 Image(this.imagePixelMap).objectFit(ImageFit.None) 99 }.width('100%').height('50%').backgroundColor('#F0F0F0') 100 } 101 ``` 102 103## 完整代码 104本例完整代码如下: 105```ts 106import image from '@ohos.multimedia.image'; 107 108@Entry 109@Component 110struct ImageEdit{ 111 @State imagePixelMap:PixelMap = undefined 112 @State edit:boolean = false 113 114 @Builder buttonModel($$:{textContent,action}){ 115 Button($$.textContent) 116 .fontSize(14) 117 .height(30) 118 .width(60) 119 .borderRadius(10) 120 .backgroundColor('#E8A027') 121 .onClick(()=>{ 122 $$.action 123 this.edit = true 124 }) 125 } 126 127 async get_pixelmap(){ 128 // 获取resourceManager资源管理 129 const context = getContext(this) 130 const resourceMgr = context.resourceManager 131 // 获取rawfile文件夹下httpimage.PNG的ArrayBuffer 132 const fileData = await resourceMgr.getMediaContent($r('app.media.httpimage')) 133 const buffer = fileData.buffer 134 // 创建imageSource 135 const imageSource = image.createImageSource(buffer) 136 // 创建PixelMap 137 const pixelMap = await imageSource.createPixelMap() 138 return pixelMap 139 } 140 141 // 对pixelMap进行裁剪 142 async crop_image(){ 143 let pixelMap = await this.get_pixelmap() 144 pixelMap.crop({x:0,y:0,size:{height:300,width:300}}) 145 this.imagePixelMap = pixelMap 146 } 147 148 // 对pixelMap进行缩放 149 async scale_image(){ 150 let pixelMap = await this.get_pixelmap() 151 pixelMap.scale(0.5,0.5) 152 this.imagePixelMap = pixelMap 153 } 154 155 // 对pixelMap进行偏移 156 async translate_image(){ 157 let pixelMap = await this.get_pixelmap() 158 pixelMap.translate(100,100); 159 this.imagePixelMap = pixelMap 160 } 161 162 // 对pixelMap进行旋转 163 async rotate_image(){ 164 let pixelMap = await this.get_pixelmap() 165 pixelMap.rotate(90); 166 this.imagePixelMap = pixelMap 167 } 168 169 // 对pixelMap进行翻转 170 async flip_image(){ 171 let pixelMap = await this.get_pixelmap() 172 pixelMap.flip(false, true); 173 this.imagePixelMap = pixelMap 174 } 175 176 // 对pixelMap进行透明度调整 177 async opacity_image(){ 178 let pixelMap = await this.get_pixelmap() 179 pixelMap.opacity(0.5); 180 this.imagePixelMap = pixelMap 181 } 182 183 build(){ 184 Column(){ 185 if(!this.edit){ 186 Row(){ 187 Image($r('app.media.httpimage')).objectFit(ImageFit.None) 188 }.width('100%').height('50%').backgroundColor('#F0F0F0') 189 }else{ 190 Row(){ 191 // 将编辑好的pixelMap传递给状态变量imagePixelMap后,通过Image组件进行渲染 192 Image(this.imagePixelMap).objectFit(ImageFit.None) 193 }.width('100%').height('50%').backgroundColor('#F0F0F0') 194 } 195 196 Flex({wrap:FlexWrap.Wrap,justifyContent:FlexAlign.SpaceEvenly}){ 197 this.buttonModel({textContent:'裁剪',action:this.crop_image()}) 198 this.buttonModel({textContent:'缩放',action:this.scale_image()}) 199 this.buttonModel({textContent:'偏移',action:this.translate_image()}) 200 this.buttonModel({textContent:'旋转',action:this.rotate_image()}) 201 this.buttonModel({textContent:'翻转',action:this.flip_image()}) 202 this.buttonModel({textContent:'透明度',action:this.opacity_image()}) 203 Button('还原') 204 .fontSize(14) 205 .height(30) 206 .width(60) 207 .borderRadius(10) 208 .margin({top:20}) 209 .backgroundColor('#A4AE77') 210 .onClick(()=>{ 211 this.edit = false 212 }) 213 } 214 .margin({top:100}) 215 .height('100%') 216 .width('100%') 217 } 218 .height('100%') 219 .width('100%') 220 } 221} 222``` 223## 参考 224- [图片解码](../application-dev/media/image-decoding.md) 225- [图片变换](../application-dev/media/image-transformation.md) 226- [Image组件](../application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-image.md) 227