出现问题的核心代码如下:
- // 显示PixelMap图像
- Image(this.currentPixelMap)
- .id('ImageContent')
- .objectFit(ImageFit.Contain)
-
- // 旋转PixelMap图像的函数
- rotateImage: (rotate: number) => void = (rotate: number) => {
- let pixelMap = componentSnapshot.getSync('ImageContent'); // 获取Image组件的组件截图
- pixelMap?.rotateSync(rotate); // 对Image组件的截图旋转相应的角度
- this.currentPixelMap = pixelMap; // 用旋转后的组件截图刷新Image组件显示的PixelMap数据
- }
每次旋转时都是对Image组件截图,并对截图内容进行旋转,然后将旋转后的内容重新显示在Image组件上。存在以下问题:
在旋转图像时,旋转的不是原始图像,而是对Image组件的截图进行旋转,并且每次旋转都是在上一次旋转得到的图像上进行旋转,而旋转角度为非90度的整数倍时,旋转后的图像尺寸会发生变化,旋转前只占据旋转后图像的一部分,连续多次旋转后,原始图像在图像中占据的部分会越来越小,因此当显示在Image组件上时,看起来图像逐渐变小。
参考代码如下:
- import image from '@ohos.multimedia.image';
- import { Context } from '@kit.AbilityKit';
-
- @Entry
- @Component
- export struct PixelMapRotateSmallerDemo {
- @State rotationPixelMap: image.PixelMap | undefined = undefined; // 旋转PixelMap
- private pixelMap: image.PixelMap | undefined = undefined; // 原始PixelMap
- private rotation: number = 0; // 旋转角度
-
- async aboutToAppear(): Promise<void> {
- let imageSource: image.ImageSource | undefined;
- try {
- // 读取图片文件,这里以Rawfile目录下的img.png图片为例
- let context = this.getUIContext().getHostContext() as Context;
- let fileData: Uint8Array = context.resourceManager.getRawFileContentSync('img.png');
- // 解码图片文件为PixelMap
- imageSource = image.createImageSource(fileData.buffer.slice(0));
- this.pixelMap = await imageSource.createPixelMap();
-
- this.rotationPixelMap = await this.getPixelmap();
- } catch (err) {
- console.error(`Failed to load image, Cause: ${JSON.stringify(err)}`);
- } finally {
- if (imageSource) {
- await imageSource.release();
- }
- }
- }
-
- async getPixelmap() {
- if (this.pixelMap === undefined) {
- return undefined;
- }
- try {
- // 从原始PixelMap读取像素数据
- let bufferSize = this.pixelMap.getPixelBytesNumber();
- let pixelsBuffer = new ArrayBuffer(bufferSize);
- this.pixelMap.readPixelsToBufferSync(pixelsBuffer);
- let info = this.pixelMap.getImageInfoSync();
- // 创建新的PixelMap,确保每次都在原图基础上旋转
- let initOpts: image.InitializationOptions = {
- size: info.size,
- srcPixelFormat: info.pixelFormat,
- };
- let pixelMap = await image.createPixelMap(pixelsBuffer, initOpts);
- return pixelMap;
- } catch (err) {
- console.error(`Failed to copy pixelmap, Cause: ${JSON.stringify(err)}`);
- return undefined;
- }
- }
-
- async rotatePixelmap() {
- // 设置旋转角度,每次旋转30度
- this.rotation = (this.rotation + 30) % 360;
- let oldPixelMap: image.PixelMap | undefined;
- try {
- let newPixelMap = await this.getPixelmap();
- if (newPixelMap === undefined) {
- return;
- }
- // 旋转PixelMap
- newPixelMap.rotateSync(this.rotation);
- // 保存旧PixelMap
- oldPixelMap = this.rotationPixelMap;
- // 更新PixelMap
- this.rotationPixelMap = newPixelMap;
- } catch (err) {
- console.error(`failed to rotate image, Cause: ${JSON.stringify(err)}`);
- } finally {
- if (oldPixelMap) {
- oldPixelMap.release();
- }
- }
- }
-
- build() {
- Column({ space: 20 }) {
- Image(this.rotationPixelMap)
- .width('100%')
- .aspectRatio(1)
- .objectFit(ImageFit.None);
-
- Button() {
- Text('Rotate')
- .padding(8)
- .fontSize(30)
- .fontColor(Color.White);
- }
- .backgroundColor('#0A59F7')
- .onClick(() => {
- this.rotatePixelmap();
- });
- }
- .width('100%')
- .height('100%')
- .justifyContent(FlexAlign.Center);
- }
- }
多次旋转图像时,确保每次旋转都是在原始图像的基础上旋转。