给image()设置.objectFit(ImageFit.Contain)属性,将图片转换成pixelMap后,对pixelMap格式的图片进行旋转,既可以达到图片旋转自适应宽高的效果。参考如下demo:// EntryAbility.ets import { UIAbility, abilityAccessCtrl, Permissions, Want, AbilityConstant } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { BusinessError } from '@kit.BasicServicesKit'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); } onDestroy() { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage) { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); const permissions: Array<Permissions> = [ 'ohos.permission.WRITE_IMAGEVIDEO', 'ohos.permission.WRITE_MEDIA', 'ohos.permission.READ_MEDIA', 'ohos.permission.MEDIA_LOCATION' ]; const atManager = abilityAccessCtrl.createAtManager(); atManager.requestPermissionsFromUser(this.context, permissions, (err, data) => { if (err) { hilog.error(0x0000, 'testTag', 'Failed to requestPermission. Cause: %{public}s', JSON.stringify(err) ?? ''); } else { hilog.info(0x0000, 'testTag', 'Succeeded in requestPermission. Data: %{public}s', JSON.stringify(data) ?? ''); } }); windowStage.getMainWindow((_err, windowClass) => { windowClass.setWindowLayoutFullScreen(false, (err) => { if (err.code) { hilog.error(0x0000, 'EntryAbility', 'Failed to set the window layout to no-full-screen mode. Cause:' + JSON.stringify(err)); return; } hilog.info(0x0000, 'EntryAbility', 'Succeeded in setting the window layout to no-full-screen mode.'); }); }); windowStage.loadContent('pages/HomePage', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口 // 1. 设置窗口全屏 let isLayoutFullScreen = true; windowClass.setWindowLayoutFullScreen(isLayoutFullScreen) .then(() => { console.info('Succeeded in setting the window layout to full-screen mode.'); }) .catch((err: BusinessError) => { console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err)); }); // 2. 获取布局避让遮挡的区域 let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例 let avoidArea = windowClass.getWindowAvoidArea(type); let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航条区域的高度 AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight); // 2. 设置状态栏和导航条隐藏 windowClass.setSpecificSystemBarEnabled('status', false) .then(() => { console.info('Succeeded in setting the status bar to be invisible.'); }) .catch((err: BusinessError) => { console.error(`Failed to set the status bar to be invisible. Code is ${err.code}, message is ${err.message}`); }); hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); } onWindowStageDestroy() { // Main window is destroyed, release UI related resources hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground() { // Ability has brought to foreground hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground() { // Ability has back to background hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } } // HomePage.ets import { image } from '@kit.ImageKit'; import getPixelMap from '../utils/DecodeUtil'; const TAG: string = 'imageEdit'; enum RotateType { CLOCKWISE, ANTI_CLOCK } @Entry @Component struct HomePage { @State currentIndex: number = 0; @State currentCropIndex: number = 0; @Provide('pixelMap') pixelMap?: image.PixelMap = undefined; @Provide('imageInfo') imageInfo: image.ImageInfo = { size: { height: 0, width: 0 }, density: 0, stride: 0, alphaType: 0, pixelFormat: 0, mimeType: '', isHdr: false }; @Provide('currentAdjustData') currentAdjustData: Array<number> = [100, 100, 100].map((item: number) => item); @Provide('isPixelMapChange') @Watch('flushPixelMap') isPixelMapChange: boolean = false; rotateImage(rotateType: RotateType) { if (rotateType === RotateType.CLOCKWISE) { if (!this.pixelMap) { return; } try { this.pixelMap.rotate(90) .then(() => { this.flushPixelMapChange(); }) } catch (error) { console.error(TAG, `there is a error in rotate process with ${error?.code}`); } } if (rotateType === RotateType.ANTI_CLOCK) { if (!this.pixelMap) { return; } try { this.pixelMap.rotate(-90) .then(() => { this.flushPixelMapChange(); }) } catch (error) { console.error(TAG, `there is a error in rotate process with ${error?.code}`); } } } flushPixelMapChange() { this.isPixelMapChange = !this.isPixelMapChange; } flushPixelMap() { const temp = this.pixelMap; this.pixelMap = undefined; this.pixelMap = temp; } pixelInit() { getPixelMap(this) .then((pixelMap?: image.PixelMap) => { if (pixelMap) { this.isPixelMapChange = !this.isPixelMapChange; this.pixelMap = pixelMap; } this.currentCropIndex = 0; this.currentAdjustData = [100, 100, 100].map((item: number) => item); }) } aboutToAppear() { this.pixelInit(); } build() { Navigation() { Stack() { Column() { Blank().height("5%") Column() { if (this.isPixelMapChange) { Image(this.pixelMap) .objectFit(ImageFit.Contain) } else { Image(this.pixelMap) .objectFit(ImageFit.Contain) } } .width('100%') .height('70%') Column() { Row() { Image($r('app.media.ic_clockwise')) .width(36) .height(36) .margin({ right: '30%' }) .onClick(() => { this.rotateImage(RotateType.CLOCKWISE); }) Image($r('app.media.ic_anti_clockwise')) .width(36) .height(36) .onClick(async () => { this.rotateImage(RotateType.ANTI_CLOCK); }) } .justifyContent(FlexAlign.Center) .width('100%') .height('100%') } .width('100%') .height('30%') .backgroundColor(Color.Black) } .width('100%') .height('100%') .backgroundColor(Color.Black) } } .titleMode(NavigationTitleMode.Mini) .backgroundColor(Color.Black) .hideBackButton(true) } } // DecodeUtil.ets import { fileIo } from '@kit.CoreFileKit'; import { image } from '@kit.ImageKit'; import { CommonConstants } from '../common/constant/CommonConstants'; const TAG: string = 'imageEdit_Decode'; /** * Async get resource fd. * * @return file fd. */ async function getResourceFd(component: Object) { const context = getContext(component); const resourceMgr = context.resourceManager; let imageBuffer = await resourceMgr.getMediaContent($r("app.media.ic_low")) let filePath = context.cacheDir + '/' + CommonConstants.RAW_FILE_NAME; let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE); fileIo.writeSync(file.fd, imageBuffer.buffer); return file.fd; } /** * Async create pixel map. * * @return pixelMa. */ export default async function getPixelMap(component: Object) { const fd = await getResourceFd(component); const imageSourceApi = image.createImageSource(fd); if (!imageSourceApi) { console.error(TAG, 'imageSourceAPI created failed!'); return; } const pixelMap = await imageSourceApi.createPixelMap({ editable: true }); return pixelMap; }
给image()设置.objectFit(ImageFit.Contain)属性,将图片转换成pixelMap后,对pixelMap格式的图片进行旋转,既可以达到图片旋转自适应宽高的效果。
参考如下demo: