編輯圖片—OpenHarmony
想了解更多關(guān)于開源的內(nèi)容,請?jiān)L問:
編輯圖片
場景說明
圖片編輯是在應(yīng)用中經(jīng)常用到的功能,比如相機(jī)拍完照片后可以對照片進(jìn)行編輯;截圖后可以對截圖進(jìn)行編輯;可以對圖庫中的圖片進(jìn)行編輯等。本例即為大家介紹如何獲取圖片的pixelMap數(shù)據(jù),并通過pixelMap對圖片進(jìn)行常見的編輯操作。
效果呈現(xiàn)
本例最終效果如下:
運(yùn)行環(huán)境
本例基于以下環(huán)境開發(fā),開發(fā)者也可以基于其他適配的版本進(jìn)行開發(fā):
- IDE: DevEco Studio 3.1 Release
- SDK: Ohos_sdk_public 3.2.12.5(API Version 9 Release)
實(shí)現(xiàn)思路
本例中展示的是對資源文件中的圖片進(jìn)行編輯,編輯操作主要分為以下三步:
- 對圖片解碼,獲取到pixelMap:先通過上下文context獲取到資源管理器resourceManager,然后通過資源管理器獲取到圖片數(shù)據(jù),然后獲取圖片的ArrayBuffer,最后通過ArrayBuffer創(chuàng)建imageSource,獲取到pixelMap,完成圖片解碼。
- 編輯pixelMap:獲取到pixelMap后就可以針對pixelMap進(jìn)行裁剪、縮放、偏移、旋轉(zhuǎn)、翻轉(zhuǎn)、調(diào)節(jié)透明度等操作。
- 將編輯好的pixelMap渲染顯示出來:完成對pixelMap的編輯后,可以通過Image組件將編輯后的pixelMap渲染顯示出來。
開發(fā)步驟
由于本例重點(diǎn)講解圖片編輯,所以開發(fā)步驟會著重講解相關(guān)實(shí)現(xiàn),不相關(guān)的內(nèi)容不做介紹,全量代碼可參考完整代碼章節(jié)。
1、對圖片進(jìn)行解碼。
先通過上下文context獲取到資源管理器resourceManager,然后通過資源管理器獲取到圖片數(shù)據(jù),然后獲取圖片的ArrayBuffer,最后通過ArrayBuffer創(chuàng)建imageSource,獲取到pixelMap,完成圖片解碼。
具體代碼如下:
async get_pixelmap(){
// 獲取resourceManager資源管理
const context = getContext(this)
const resourceMgr = context.resourceManager
// 獲取rawfile文件夾下httpimage.PNG的ArrayBuffer
const fileData = await resourceMgr.getMediaContent($r('app.media.httpimage'))
const buffer = fileData.buffer
// 創(chuàng)建imageSource
const imageSource = image.createImageSource(buffer)
// 創(chuàng)建PixelMap
const pixelMap = await imageSource.createPixelMap()
return pixelMap
}
2、編輯pixelMap。
分別通過以下方法對pixelMap進(jìn)行裁剪、縮放、偏移、旋轉(zhuǎn)、翻轉(zhuǎn)、調(diào)節(jié)透明度等操作:crop、scale、translate、rotate、flip、opacity。
具體代碼如下:
// 對pixelMap進(jìn)行裁剪
async crop_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.crop({x:0,y:0,size:{height:300,width:300}})
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行縮放
async scale_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.scale(0.5,0.5)
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行偏移
async translate_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.translate(100,100);
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行旋轉(zhuǎn)
async rotate_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.rotate(90);
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行翻轉(zhuǎn)
async flip_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.flip(false, true);
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行透明度調(diào)整
async opacity_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.opacity(0.5);
this.imagePixelMap = pixelMap
}
3、通過Image組件將編輯后的pixelMap渲染顯示出來。
第2步中將編輯好的pixelMap傳遞給狀態(tài)變量imagePixelMap,本步中直接將imagePixelMap傳入Image組件進(jìn)行渲染顯示。
具體代碼如下:
if(!this.edit){
Row(){
Image($r('app.media.httpimage')).objectFit(ImageFit.None)
}.width('100%').height('50%').backgroundColor('#F0F0F0')
}else{
Row(){
// 將編輯好的pixelMap傳遞給狀態(tài)變量imagePixelMap后,通過Image組件進(jìn)行渲染
Image(this.imagePixelMap).objectFit(ImageFit.None)
}.width('100%').height('50%').backgroundColor('#F0F0F0')
}
完整代碼
本例完整代碼如下:
import image from '@ohos.multimedia.image';
@Entry
@Component
struct ImageEdit{
@State imagePixelMap:PixelMap = undefined
@State edit:boolean = false
@Builder buttonModel($$:{textContent,action}){
Button($$.textContent)
.fontSize(14)
.height(30)
.width(60)
.borderRadius(10)
.backgroundColor('#E8A027')
.onClick(()=>{
$$.action
this.edit = true
})
}
async get_pixelmap(){
// 獲取resourceManager資源管理
const context = getContext(this)
const resourceMgr = context.resourceManager
// 獲取rawfile文件夾下httpimage.PNG的ArrayBuffer
const fileData = await resourceMgr.getMediaContent($r('app.media.httpimage'))
const buffer = fileData.buffer
// 創(chuàng)建imageSource
const imageSource = image.createImageSource(buffer)
// 創(chuàng)建PixelMap
const pixelMap = await imageSource.createPixelMap()
return pixelMap
}
// 對pixelMap進(jìn)行裁剪
async crop_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.crop({x:0,y:0,size:{height:300,width:300}})
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行縮放
async scale_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.scale(0.5,0.5)
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行偏移
async translate_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.translate(100,100);
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行旋轉(zhuǎn)
async rotate_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.rotate(90);
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行翻轉(zhuǎn)
async flip_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.flip(false, true);
this.imagePixelMap = pixelMap
}
// 對pixelMap進(jìn)行透明度調(diào)整
async opacity_image(){
let pixelMap = await this.get_pixelmap()
pixelMap.opacity(0.5);
this.imagePixelMap = pixelMap
}
build(){
Column(){
if(!this.edit){
Row(){
Image($r('app.media.httpimage')).objectFit(ImageFit.None)
}.width('100%').height('50%').backgroundColor('#F0F0F0')
}else{
Row(){
// 將編輯好的pixelMap傳遞給狀態(tài)變量imagePixelMap后,通過Image組件進(jìn)行渲染
Image(this.imagePixelMap).objectFit(ImageFit.None)
}.width('100%').height('50%').backgroundColor('#F0F0F0')
}
Flex({wrap:FlexWrap.Wrap,justifyContent:FlexAlign.SpaceEvenly}){
this.buttonModel({textContent:'裁剪',action:this.crop_image()})
this.buttonModel({textContent:'縮放',action:this.scale_image()})
this.buttonModel({textContent:'偏移',action:this.translate_image()})
this.buttonModel({textContent:'旋轉(zhuǎn)',action:this.rotate_image()})
this.buttonModel({textContent:'翻轉(zhuǎn)',action:this.flip_image()})
this.buttonModel({textContent:'透明度',action:this.opacity_image()})
Button('還原')
.fontSize(14)
.height(30)
.width(60)
.borderRadius(10)
.margin({top:20})
.backgroundColor('#A4AE77')
.onClick(()=>{
this.edit = false
})
}
.margin({top:100})
.height('100%')
.width('100%')
}
.height('100%')
.width('100%')
}
}