HarmonyOS:使用PhotoPicker组件访问图片/视频

一、前言

当应用需要读取用户图片时,开发者可以在应用界面中嵌入PhotoPicker组件,在用户选择所需要的图片资源后,直接返回该图片资源,而不需要授予应用读取图片文件的权限,即可完成图片或视频文件的访问和读取。

界面效果如图所示。

在这里插入图片描述

在这里插入图片描述

二、开发步骤

  1. 导入PhotoPicker模块文件
import {
  PhotoPickerComponent,
  PickerController,
  PickerOptions,
  DataType,
  BaseItemInfo,
  ItemInfo,
  PhotoBrowserInfo,
  ItemType,
  ClickType,
  MaxCountType,
  PhotoBrowserRange,
  PhotoBrowserUIElement,
  ReminderMode,
  ItemsDeletedCallback,
  ExceedMaxSelectedCallback,
  CurrentAlbumDeletedCallback
} from '@ohos.file.PhotoPickerComponent';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
  1. 创建Picker组件配置选项实例(PickerOptions)和控制实例(PickerController)。
    通过PickerOptions,开发者可配置Picker宫格的样式(如勾选框背景色、文本颜色等)、滑动预览方向、最大选择数量等参数,详见PickerOptions API参考。

    通过PickerController,应用可向Picker组件发送数据。
  // 组件初始化时设置参数信息
  pickerOptions: PickerOptions = new PickerOptions();

  // 组件初始化完成后,可控制组件部分行为
  @State pickerController: PickerController = new PickerController();

  // 已选择的图片
  @State selectUris: Array<string> = new Array<string>();

  //目前选择的图片
  @State currentUri: string = '';
  
  //是否显示大图
  @State isBrowserShow: boolean = false;
  1. 应用界面出现时,初始化组件配置选项实例(PickerOptions)。
    此处仅列举实例用到的参数,当前支持的配置项及其取值范围详见PickerOptions API参考。
// 设置picker宫格页数据类型
this.pickerOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE // 图片和照片都显示;
// 最大选择数量
this.pickerOptions.maxSelectNumber = 5;
// 超出最大选择数量时
this.pickerOptions.maxSelectedReminderMode = ReminderMode.TOAST;
// 是否展示搜索框,默认false
this.pickerOptions.isSearchSupported = true;
// 是否支持拍照,默认false
this.pickerOptions.isPhotoTakingSupported = true;
  1. 实现回调函数。
    通过实现以下回调事件,可在用户在界面操作时,将相关信息报给应用进行处理。
  • 进退大图、切换大图回调,上报的大图相关信息。
  • 勾选图片/视频,将上报图片URI供应用使用
    • 说明
      • 回调返回的所有URI均为只读URI,开发者可以根据结果集中的URI读取文件数据。但不能在Picker的回调中直接使用此UR
        打开文档,需要定义一个全局变量保存URI,样例可参考指定URI读取文件数据、指定URI获取图片或视频资源。
      • 如需获取元数据,可通过文件管理和文件URI接口,根据uri获取部分文件属性信息,比如文件大小、访问时间、修改时间
        文件名、文件路径等。
  • 点击图片(缩略图item),将上报图片/视频信息ItemInfo;点击相机item,可拉起系统相机或应用自行处理。
// 资源被选中回调,返回资源的信息,以及选中方式
private onItemClicked(itemInfo: ItemInfo, clickType: ClickType): boolean {
  if (!itemInfo) {
    return false;
  }
  let type: ItemType | undefined = itemInfo.itemType;
  let uri: string | undefined = itemInfo.uri;
  if (type === ItemType.CAMERA) {
    // 点击相机item
    return true; // 返回true则拉起系统相机,若应用需要自行处理则返回false。
  } else {
    if (clickType === ClickType.SELECTED) {
      // 应用做自己的业务处理
      if (uri) {
        this.selectUris.push(uri);
        this.pickerOptions.preselectedUris = [...this.selectUris];
      }
      return true; // 返回true则勾选,否则则不响应勾选。
    } else {
      if (uri) {
        this.selectUris = this.selectUris.filter((item: string) => {
          return item != uri;
        });
        this.pickerOptions.preselectedUris = [...this.selectUris];
      }
    }
    return true;
  }
}

// 进入大图的回调
private onEnterPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {
  this.isBrowserShow = true;
  return true;
}

// 退出大图的回调
private onExitPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {
  this.isBrowserShow = false;
  return true;
}

// 接收到该回调后,便可通过pickerController相关接口向picker发送数据,在此之前不生效。
private onPickerControllerReady(): void {
  let elements: number[] = [PhotoBrowserUIElement.BACK_BUTTON];
  this.pickerController.setPhotoBrowserUIElementVisibility(elements, false); // 设置大图页不显示返回按钮
}

// 大图左右滑动的回调
private onPhotoBrowserChanged(browserItemInfo: BaseItemInfo): boolean {
  this.currentUri = browserItemInfo.uri ?? '';
  return true;
}

// 已勾选图片被删除时的回调
private onSelectedItemsDeleted(baseItemInfos: Array<BaseItemInfo>): void {
}

// 超过最大选择数量再次点击时的回调
private onExceedMaxSelected(exceedMaxCountType: MaxCountType): void {
}

// 当前相册被删除时的回调
private onCurrentAlbumDeleted(): void {
}
  1. 创建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(),
    onPhotoBrowserChanged: (browserItemInfo: BaseItemInfo): boolean => this.onPhotoBrowserChanged(browserItemInfo),
    onSelectedItemsDeleted: (BaseItemInfo: Array<BaseItemInfo>) => this.onSelectedItemsDeleted(BaseItemInfo),
    onExceedMaxSelected: (exceedMaxCountType: MaxCountType) => this.onExceedMaxSelected(exceedMaxCountType),
    onCurrentAlbumDeleted: () => this.onCurrentAlbumDeleted(),
    pickerController: this.pickerController,
  })
  1. 通过PickerController向Picker组件发送数据,实现控制PhotoPickerComponent组件行为

三、完整示例代码

import {
  PhotoPickerComponent,
  PickerController,
  PickerOptions,
  DataType,
  BaseItemInfo,
  ItemInfo,
  PhotoBrowserInfo,
  ItemType,
  ClickType,
  MaxCountType,
  PhotoBrowserRange,
  PhotoBrowserUIElement,
  ReminderMode,
  ItemsDeletedCallback,
  ExceedMaxSelectedCallback,
  CurrentAlbumDeletedCallback
} from '@ohos.file.PhotoPickerComponent';
import photoAccessHelper from '@ohos.file.photoAccessHelper';

@Entry
@Component
struct PhotoPickerComponentDemo {
  // 组件初始化时设置参数信息
  pickerOptions: PickerOptions = new PickerOptions();

  // 组件初始化完成后,可控制组件部分行为
  @State pickerController: PickerController = new PickerController();

  // 已选择的图片
  @State selectUris: Array<string> = new Array<string>();

  //目前选择的图片
  @State currentUri: string = '';

  //是否显示大图
  @State isBrowserShow: boolean = false;

  aboutToAppear() {
    // 设置picker宫格页数据类型
    this.pickerOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE // 图片和照片都显示;
    // 最大选择数量
    this.pickerOptions.maxSelectNumber = 5;
    // 超出最大选择数量时
    this.pickerOptions.maxSelectedReminderMode = ReminderMode.TOAST;
    // 是否展示搜索框,默认false
    this.pickerOptions.isSearchSupported = true;
    // 是否支持拍照,默认false
    this.pickerOptions.isPhotoTakingSupported = true;

  }

  // 资源被选中回调,返回资源的信息,以及选中方式
  private onItemClicked(itemInfo: ItemInfo, clickType: ClickType): boolean {
    if (!itemInfo) {
      return false;
    }
    let type: ItemType | undefined = itemInfo.itemType;
    let uri: string | undefined = itemInfo.uri;
    if (type === ItemType.CAMERA) {
      // 点击相机item
      return true; // 返回true则拉起系统相机,若应用需要自行处理则返回false。
    } else {
      if (clickType === ClickType.SELECTED) {
        // 应用做自己的业务处理
        if (uri) {
          this.selectUris.push(uri);
          this.pickerOptions.preselectedUris = [...this.selectUris];
        }
        return true; // 返回true则勾选,否则则不响应勾选。
      } else {
        if (uri) {
          this.selectUris = this.selectUris.filter((item: string) => {
            return item != uri;
          });
          this.pickerOptions.preselectedUris = [...this.selectUris];
        }
      }
      return true;
    }
  }

  // 进入大图的回调
  private onEnterPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {
    this.isBrowserShow = true;
    return true;
  }

  // 退出大图的回调
  private onExitPhotoBrowser(photoBrowserInfo: PhotoBrowserInfo): boolean {
    this.isBrowserShow = false;
    return true;
  }

  // 接收到该回调后,便可通过pickerController相关接口向picker发送数据,在此之前不生效。
  private onPickerControllerReady(): void {
  }

  // 大图左右滑动的回调
  private onPhotoBrowserChanged(browserItemInfo: BaseItemInfo): boolean {
    this.currentUri = browserItemInfo.uri ?? '';
    return true;
  }

  // 已勾选图片被删除时的回调
  private onSelectedItemsDeleted(baseItemInfos: Array<BaseItemInfo>): void {
  }

  // 超过最大选择数量再次点击时的回调
  private onExceedMaxSelected(exceedMaxCountType: MaxCountType): void {
  }

  // 当前相册被删除时的回调
  private onCurrentAlbumDeleted(): void {
  }

  build() {
    Flex({
      direction: FlexDirection.Column,
      alignItems: ItemAlign.Start
    }) {
      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(),
        onPhotoBrowserChanged: (browserItemInfo: BaseItemInfo): boolean => this.onPhotoBrowserChanged(browserItemInfo),
        onSelectedItemsDeleted: (BaseItemInfo: Array<BaseItemInfo>) => this.onSelectedItemsDeleted(BaseItemInfo),
        onExceedMaxSelected: (exceedMaxCountType: MaxCountType) => this.onExceedMaxSelected(exceedMaxCountType),
        onCurrentAlbumDeleted: () => this.onCurrentAlbumDeleted(),
        pickerController: this.pickerController,
      })

      // 这里模拟应用侧底部的选择栏
      if (this.isBrowserShow) {
        //已选择的图片缩影图
        Row() {
          ForEach(this.selectUris, (uri: string) => {
            if (uri === this.currentUri) {
              Image(uri).height(50).width(50)
                .onClick(() => {
                })
                .borderWidth(1)
                .borderColor('red')
            } else {
              Image(uri).height(50).width(50).onClick(() => {
                this.pickerController.setData(DataType.SET_SELECTED_URIS, this.selectUris);
                this.pickerController.setPhotoBrowserItem(uri, PhotoBrowserRange.ALL);
              })
            }
          }, (uri: string) => JSON.stringify(uri))
        }.alignSelf(ItemAlign.Center).margin(this.selectUris.length ? 10 : 0)
      } else {
        // 进入大图,预览已选择的图片
        Button('预览').width('33%').alignSelf(ItemAlign.Start).height('5%').margin(10).onClick(() => {
          if (this.selectUris.length > 0) {
            this.pickerController.setPhotoBrowserItem(this.selectUris[0], PhotoBrowserRange.SELECTED_ONLY);
          }
        })
      }
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值