文档管理中心

图片尺寸约束

问题现象

在使用Image组件时,如何实现以下场景:

  1. 图片不进行任何缩放、裁剪或拉伸,直接按图源宽度和高度渲染。
  2. 如何自定义图片的显示尺寸,使其按相应比例进行缩放。

背景知识

  • objectFit:设置图片的填充效果,使图片按照对应宽高比进行缩小或者放大。
  • PixelMap:图像像素类,用于读取或写入图像数据以及获取图像信息。
  • fitOriginalSize:设置图片的显示尺寸是否跟随图源尺寸,当图片组件已设置width、height属性时,该属性不生效。

解决方案

  • 场景一:通过将Image的fitoriginalsize属性设为true,可以在Image组件未设置宽高的情况下适应图源尺寸。具体参考Column宽高自适应背景图片大小
  • 场景二:定义DecodingOptions,通过ImageSource构建PixelMap对象,并基于目标尺寸计算缩放比例后调用scaleSync方法实现动态图片缩放。
    1. 获取原始尺寸,通过pixelMap.getImageInfo获取图片的原始宽度和高度。
    2. 计算缩放比例,分别计算宽度和高度需要缩放的比例。
    3. 调用scaleSync方法,按照计算出的比例进行缩放。缩放操作会直接修改PixelMap对象本身。
    具体代码如下:
    import image from '@ohos.multimedia.image';
    import fs from '@ohos.file.fs';
    
    @Entry
    @Component
    struct Index {
      @State pixelMap: PixelMap | undefined = undefined;
      context: Context = this.getUIContext().getHostContext() as Context;
      path: string = this.context.filesDir + '/hehe.jpg';
      decodingOptions: image.DecodingOptions = {
        editable: true,
        desiredPixelFormat: 3,
      };
    
      async aboutToAppear(): Promise<void> {
        let resourceManager = this.context.resourceManager;
        let imageArray =
          await resourceManager.getMediaContent($r('app.media.BigImage').id); // 需开发者自行更换图片
        let file = fs.openSync(this.path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
        try {
          fs.writeSync(file.fd, imageArray.buffer);
        } catch (err) {
        } finally {
          fs.closeSync(file);
        }
      }
    
      async packingDetail(targetWidth: number, targetHeight: number) {
        if (this.pixelMap) {
          let imageInfo = await this.pixelMap.getImageInfo();
          // 计算压缩比
          let scaleX: number = targetWidth / imageInfo.size.width;
          let scaleY: number = targetHeight / imageInfo.size.height;
          this.pixelMap.scaleSync(scaleX, scaleY);
        }
      }
    
      build() {
        Row() {
          Column() {
            Image(this.pixelMap)
              .width(200)
              .height(200)
              .backgroundColor(Color.Gray)
              .margin({ bottom: 40 })
              .objectFit(ImageFit.Contain)
    
            Button('1:3').onClick(async () => {
              const imageSource: image.ImageSource = image.createImageSource(this.path);
              // 创建pixelMap
              this.pixelMap = await imageSource.createPixelMap(this.decodingOptions);
              // 指定压缩宽、高
              this.packingDetail(100, 300);
            }).margin({ bottom: 20 })
    
            Button('1:2').onClick(async () => {
              // path为已获得的沙箱路径
              const imageSource: image.ImageSource = image.createImageSource(this.path);
              // 创建pixelMap
              this.pixelMap = await imageSource.createPixelMap(this.decodingOptions);
              // 指定压缩宽、高
              this.packingDetail(100, 200);
            })
          }
          .width('100%')
        }
        .height('100%')
      }
    }

常见FAQ

Q:ImageAnimator在设置了fixedSize之后,图片不会跟随组件宽高做拉伸。

A:设置fixedSize属性后,ImageAnimator将维持图片的原始宽高比。当图片原始尺寸与组件尺寸不一致时,图片会适配至ImageAnimator的宽高范围内显示,而不会被拉伸变形。

在 FAQ 中进行搜索
请输入您想要搜索的关键词