HarmonyOS【PixelMap】crop后,显示到Image控件中仍然未被截取

按照以下代码,点击添加照片按钮,期望显示一张被截取了一半的图片,但不管origin还是cropped,显示在Image中的都是完整而未被截取的图片。(后来试着多点几次添加同一张照片,有点时候能小概率(低于50%)显示两个Image均为截取后的图片)

import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo, picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';

@Entry
@Component
struct CropPage {
  @State origin: PixelMap | undefined = undefined
  @State cropped: PixelMap | undefined = undefined
  private async decodeImage(uri: string) {
    try {
      let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)
      const imageSourceApi = image.createImageSource(file.fd)
      imageSourceApi.getImageInfo(0, (error: BusinessError, imageInfo) => {
        if (imageInfo == undefined) {
          // log.e(error)
        }
        console.log(`imageInfo:  ${JSON.stringify(imageInfo)}`)
      })
      return await imageSourceApi.createPixelMap()
    } catch (error) {
      // log.e(error)
      return undefined
    }
  }

  build() {
    Column() {
      Button('添加照片')
        .onClick(async () => {
          let uris = await selectPhoto({
            MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE,
            maxSelectNumber: 1,
            isPhotoTakingSupported: false,
            recommendationOptions: {
              recommendationType: photoAccessHelper.RecommendationType.PROFILE_PICTURE,
            }
          })
          if (uris.length == 0) {
            return
          }
          this.origin = await this.decodeImage(uris[0])
          if (this.origin) {
            let info = await this.origin.getImageInfo()
            this.origin.crop({
              x: 0, y: 0,
              size: {
                width: info.size.width,
                height: info.size.height / 2
              }
            })
            this.cropped = this.origin
          }
        })

      Image(this.origin)
        .width('100%')
        .height('100%')
        .layoutWeight(1)
        .objectFit(ImageFit.Contain)

      Image(this.cropped)
        .width('100%')
        .height('100%')
        .layoutWeight(1)
        .objectFit(ImageFit.Contain)
    }
    .width(`100%`)
  }
}

const PHOTO_DEFAULT_SELECT_NUMBER: number = 9; //数量
/**
 * 通过选择模式拉起photoPicker界面,用户可以选择一个或多个图片/视频。
 * @param options
 * @returns
 */
async function selectPhoto(options?: PhotoSelectOptions): Promise<Array<string>> {
  try {
    if (!options) {
      options = new PhotoSelectOptions();
    }
    if (!options.MIMEType) { //可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。
      options.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
    }
    if (!options.maxSelectNumber) { //选择媒体文件数量的最大值,默认9
      options.maxSelectNumber = PHOTO_DEFAULT_SELECT_NUMBER;
    }
    if (options.isPhotoTakingSupported == undefined) {
      options.isPhotoTakingSupported = true; //支持拍照。
    }
    if (options.isEditSupported == undefined) {
      options.isEditSupported = true; //支持编辑照片。
    }
    if (options.isSearchSupported == undefined) {
      options.isSearchSupported = true; //支持编辑照片。
    }
    let photoSelectOptions: photoAccessHelper.PhotoSelectOptions = {
      MIMEType: options.MIMEType,
      maxSelectNumber: options.maxSelectNumber,
      isPhotoTakingSupported: options.isPhotoTakingSupported,
      isEditSupported: options.isEditSupported,
      isSearchSupported: options.isSearchSupported,
      recommendationOptions: options.recommendationOptions,
      preselectedUris: options.preselectedUris
    }
    let photoPicker = new photoAccessHelper.PhotoViewPicker();
    let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(photoSelectOptions)
    if (photoSelectResult && photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) {
      return photoSelectResult.photoUris
    } else {
      return [];
    }
  } catch (err) {
    console.error(err)
    return [];
  }
}

class PhotoSelectOptions {
  MIMEType?: photoAccessHelper.PhotoViewMIMETypes = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; //可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。
  maxSelectNumber?: number = PHOTO_DEFAULT_SELECT_NUMBER; //选择媒体文件数量的最大值(默认值为50,最大值为500)。
  isPhotoTakingSupported?: boolean = true; //支持拍照。
  isEditSupported?: boolean = true; //支持编辑照片。
  isSearchSupported?: boolean = true; //支持搜索。
  recommendationOptions?: photoAccessHelper.RecommendationOptions; //支持照片推荐。
  preselectedUris?: Array<string>; //预选择图片的uri数据。
}
HarmonyOS
3天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zxjiu

展示的就是同一张图片。参考以下demo:

import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo, picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';

const PHOTO_DEFAULT_SELECT_NUMBER: number = 9; //数量

class PhotoSelectOptions {
  MIMEType?: photoAccessHelper.PhotoViewMIMETypes = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; //可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。
  maxSelectNumber?: number = PHOTO_DEFAULT_SELECT_NUMBER; //选择媒体文件数量的最大值(默认值为50,最大值为500)。
  isPhotoTakingSupported?: boolean = true; //支持拍照。
  isEditSupported?: boolean = true; //支持编辑照片。
  isSearchSupported?: boolean = true; //支持搜索。
  recommendationOptions?: photoAccessHelper.RecommendationOptions; //支持照片推荐。
  preselectedUris?: Array<string>; //预选择图片的uri数据。
}

async function selectPhoto(options?: PhotoSelectOptions): Promise<Array<string>> {
  try {
    if (!options) {
      options = new PhotoSelectOptions();
    }
    if (!options.MIMEType) { //可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。
      options.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
    }
    if (!options.maxSelectNumber) { //选择媒体文件数量的最大值,默认9
      options.maxSelectNumber = PHOTO_DEFAULT_SELECT_NUMBER;
    }
    if (options.isPhotoTakingSupported == undefined) {
      options.isPhotoTakingSupported = true; //支持拍照。
    }
    if (options.isEditSupported == undefined) {
      options.isEditSupported = true; //支持编辑照片。
    }
    if (options.isSearchSupported == undefined) {
      options.isSearchSupported = true; //支持编辑照片。
    }
    let photoSelectOptions: photoAccessHelper.PhotoSelectOptions = {
      MIMEType: options.MIMEType,
      maxSelectNumber: options.maxSelectNumber,
      isPhotoTakingSupported: options.isPhotoTakingSupported,
      isEditSupported: options.isEditSupported,
      isSearchSupported: options.isSearchSupported,
      recommendationOptions: options.recommendationOptions,
      preselectedUris: options.preselectedUris
    }
    let photoPicker = new photoAccessHelper.PhotoViewPicker();
    let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(photoSelectOptions)
    if (photoSelectResult && photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) {
      return photoSelectResult.photoUris
    } else {
      return [];
    }
  } catch (err) {
    console.error(err)
    return [];
  }
}

@Entry
@Component
struct Index {
  @State selectedUri:string = ''
  @State origin: PixelMap | undefined = undefined
  private async decodeImage(uri: string) {
    try {
      let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)
      const imageSourceApi = image.createImageSource(file.fd)
      imageSourceApi.getImageInfo(0, (error: BusinessError, imageInfo) => {
        if (imageInfo == undefined) {
        }
        console.log('imageInfo = '+  JSON.stringify(imageInfo))
      })
      let decodingOptions: image.DecodingOptions = {
        editable: true,
        desiredPixelFormat: 3,
      }
      return await imageSourceApi.createPixelMap(decodingOptions)
    } catch (error) {
      return undefined
    }
  }

  build() {
    Column({space:20}) {
      Button('添加照片')
        .onClick(async () => {
          let uris = await selectPhoto({
            MIMEType: picker.PhotoViewMIMETypes.IMAGE_TYPE,
            maxSelectNumber: 1,
            isPhotoTakingSupported: false,
            recommendationOptions: {
              recommendationType: photoAccessHelper.RecommendationType.PROFILE_PICTURE,
            }
          })
          if (uris.length == 0) {
            return
          }
          this.selectedUri = uris[0]
        })
      Image(this.selectedUri)
        .width('100%')
        .height('400vp')
        .layoutWeight(1)
        .objectFit(ImageFit.Contain)

      Button('裁剪')
        .onClick(async () => {
          this.origin = await this.decodeImage(this.selectedUri)
          if (this.origin) {
            let info = await this.origin.getImageInfo()
            let region: image.Region = { x: 0, y: 0, size: { height: info.size.height/3, width: info.size.width } };
            this.origin.crop(region, (err: BusinessError) => {
              if (err != undefined) {
                console.error("Failed to crop pixelmap.");
                return;
              } else {
                console.info("Succeeded in cropping pixelmap.");
              }
            })
          }
        })
      Image(this.origin)
        .width('100%')
        .height('400vp')
        .layoutWeight(1)
        .objectFit(ImageFit.Contain)
    }
    .width(`100%`)
  }
}
分享
微博
QQ
微信
回复
3天前
相关问题
如何将PixelMap的数据存储数据库
1873浏览 • 1回复 待解决
HarmonyOS RelativeContainer子控件显示问题
368浏览 • 1回复 待解决
HarmonyOS Tabs 控件 底部显示不全
35浏览 • 1回复 待解决
Native Image模块API-OH_PixelMap_CreatePixelMap
1748浏览 • 1回复 待解决
如何获取窗口截图并显示Image
419浏览 • 1回复 待解决