鸿蒙选择相册里的图片并进行上传

567 阅读2分钟

利用 AlbumPickerComponentPhotoPickerComponent 实现选择相册里的图片

一、实现效果

2024-10-0808.06.03-ezgif.com-video-to-gif-converter.gif

二、AlbumPickerComponent 展示相册列表

@Component
struct ChooseAlbum{
  albumPickerOptions: AlbumPickerOptions = new AlbumPickerOptions();

  private onAlbumClick(albumInfo: AlbumInfo): boolean {
    if (albumInfo?.uri) {
      // 通过pickerController向PhotoPickerComponent发送消息,通知其刷新
      RouterManager.goToNormalPageWithParam<AlbumInfo>('ChoosePhoto',albumInfo,(popInfo: PopInfo)=>{
        RouterManager.popToLastWithIndex(2,popInfo.result)
      })
    }
    WSLToastDismiss()
    return true;
  }

  build() {
    NavDestination(){
      Stack(){
        AlbumPickerComponent({
          albumPickerOptions: this.albumPickerOptions,
          onAlbumClick:(albumInfo: AlbumInfo): boolean => this.onAlbumClick(albumInfo),
        })
          .height('100%')
          .width('100%')
      }
      .width('100%')
      .height('100%')
    }
    .title('选择相册')
    .onHidden(()=>{
      WSLToastDismiss()
    })
    .onReady(async (c: NavDestinationContext)=>{

    })
  }
}

这里需要注意处理一下 onAlbumClick 点击事件,事件会返回所点击的相册 AlbumInfo 对象,通过它的 URI 告诉图片选择器 PhotoPickerComponent 需要展示的图片集合。

三、PhotoPickerComponent 图片选择器展示相册中的图片

PhotoPickerComponent({
  pickerOptions: this.pickerOptions,
  onItemClicked: (itemInfo: ItemInfo, clickType: ClickType): boolean => this.onItemClicked(itemInfo, clickType),
  onEnterPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean => this.onEnterPhotoBrowser(photoBrowserInfo),
  onExitPhotoBrowser: (photoBrowserInfo: PhotoBrowserInfo): boolean => this.onExitPhotoBrowser(photoBrowserInfo),
  onPickerControllerReady: (): void => this.onPickerControllerReady(),
  pickerController: this.pickerController,
})
  .width('100%')
  .layoutWeight(1)

PhotoPickerComponent 组件两重要的方法是:onPickerControllerReady、onItemClicked

1、onPickerControllerReady 只有在这个回调方法里设置 PickerController 图片的展示内容才有效。所以,从相册列表页面传入的 AlbumInfo 对象可以在这个方法回调里进行设置从而刷新图片选择器的内容。

private onPickerControllerReady(): void {
  // 通过相册对象albumInfo刷新图片,在此之前不生效。
  this.pickerController.setData(DataType.SET_ALBUM_URI,this.albumInfo?.uri!)
}

2、onItemClicked 图片选择器选择图片事件回调,获取图片的 URI

private onItemClicked(itemInfo: ItemInfo, clickType: ClickType): boolean {
  //通过 ItemInfo 进行图片的操作
}

四、上传相册中的图片到服务器

  static async APIPublicUpLoadFileTypeUriRequest<T extends NetResultDefaultModel>(uri: string,context: Context,serviceType: ServiceType,api: NormalAPI,param?: object | undefined,isCheckResultStatus = true,isNeedAuthUser = true) : Promise<T | null>{
    try {
      const fileType = 'jpg'
      // 拷贝图片到临时文件
      const fileName = Date.now() + '.' + fileType
      const copyFilePath = context.cacheDir + '/' + fileName
      const file = fs.openSync(uri, fs.OpenMode.READ_ONLY)
      fs.copyFileSync(file.fd, copyFilePath)
      let netInterface = HMNetWork.GetBaseUrl(serviceType,HMNetWork.CurrentServiceMode) + HMNetWork.GetNetInterfaceWithAPI(serviceType,api)
      // formData对象创建
      let formData = new FormData()
      formData.append('file', copyFilePath)
      // 开始上传
      let r: AxiosResponse<T> | null = await axios.post<T, AxiosResponse<T>, FormData>(netInterface, formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
        context: context,
      })
      //上传完清除临时文件
      fs.rmdirSync(copyFilePath)
      let model : T | null = r?.data ?? null
      //上传结果判断
      let requestIsSucceeded = (NetResultDefaultModel.isNetSucceeded(model) || !isCheckResultStatus)
      //错误提示
      if(!requestIsSucceeded && isCheckResultStatus){
        WSLToastShow({ content: model?.msg??'访问出错了',toastType: ToastType.ToastNormalNoShowDefaultTitle })
      }
      return requestIsSucceeded ? model : null
    } catch (e){
      return null
    }
  }
}

APIPublicUpLoadFileTypeUriRequest 是自定义的上传图片的方法,参数 uri 就是上一步选中的相册中的图片路径,这里要注意的是,需将相册中的图片先拷贝到一个临时文件,待上传图片完成后再将这个临时文件删除。

以上就是相册选择的图片进行上传的步骤,希望能够帮助到大家[抱拳][抱拳][抱拳]