鸿蒙开发中快速获取相册图片的缩略图

开发背景

在日常开发中,常见选择图库照片,或者视频,进行列表显示。例如微信朋友圈9宫格,相册等。该情况下,一般都是加载图片的缩略图。点击item后加载图片跟视频详情。

技术方案

1、直接获取pixmap

javascript 复制代码
async function getThumbnail(phAccessHelper: photoAccessHelper.PhotoAccessHelper) {
  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
  let fetchOptions: photoAccessHelper.FetchOptions = {
    fetchColumns: [],
    predicates: predicates
  };

  try {
    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
    console.info('getAssets photoAsset.displayName : ' + photoAsset.displayName);
    let size: image.Size = { width: 720, height: 720 }; // 控制缩略图显示大小
    let pixelMap: image.PixelMap =  await photoAsset.getThumbnail(size);
    let imageInfo: image.ImageInfo = await pixelMap.getImageInfo()
    console.info('getThumbnail successful, pixelMap ImageInfo size: ' + JSON.stringify(imageInfo.size));
    fetchResult.close();
  } catch (err) {
    console.error('getThumbnail failed with err: ' + err);
  }
}

该可以控制缩略图大小,获取的是pixelMap 需要单独处理下内存加载问题,不推荐在列表中显示

2、直接读取相册数据库中的图片的缩略图

typescript 复制代码
export function getThumbnailJpgURI(sourceUri:string,modifiedDate:number,path?:string) :string{
  return `${sourceUri}?timestampAPP=${modifiedDate}&oper=thumbnail&width=0&height=0&path=${path ?? ''}`;
}

该方案提供的缩略图uri 可以直接设置在Image组件中,读取的是图库数据库中的缩略图,所以不需要单独处理内存,较为推荐。ps:该方法中uri 不是图片的filepath,是图库提供的uri路径。只有保存在图库的图片或者视频才可以使用该方法。 uri例子:file://media/Photo/59/IMG_1761224543_046/IMG_046.webp 跟filepath不是一个东西

代码实现

index 页面

scss 复制代码
import { getImageUris, getThumbnailJpgURI, getVideoUris } from '../utils/ImageUtils';

@Entry
@Component
struct Index {
  @State @Watch('getImageUri') imgUri:string = ""
  @State @Watch('getVideoUri') videoUri:string = ""
  getImageUri() {
    console.log("lsk 图片uri"+this.imgUri)
  }
  getVideoUri() {
    console.log("lsk 视频uri"+this.imgUri)
  }
  build() {
    Column({ space: 10 }) {
      Row({space: 20}) {
     Column({space: 10}){
        Text("图片的缩略图").fontSize(15)
       // 图片的
       Image(this.imgUri?getThumbnailJpgURI(this.imgUri,new Date().getTime()):$r('app.media.default_picture'))
         .width(100)
         .aspectRatio(1)
         .objectFit(ImageFit.Cover)
     }
        Column({space: 10}){
          Text("视频的缩略图").fontSize(15)
          // 图片的
          Image(this.videoUri?getThumbnailJpgURI(this.videoUri,new Date().getTime()):$r('app.media.default_video'))
            .width(100)
            .aspectRatio(1)
            .objectFit(ImageFit.Cover)
        }
      }
      Button('获取图片uri').width('80%').height(40).onClick(async () => {
        getImageUris((uris) => {
          if (uris.length >= 0) {
            this.imgUri = uris[0]
          }
     })
      })
        .margin({top: 30})
      Button('获取视频uri').width('80%').height(40).onClick(async () => {
        getVideoUris((uris) => {
          if (uris.length >= 0) {
            this.videoUri = uris[0]
          }
     })
      })
    }
    .justifyContent(FlexAlign.Center)
    .height('100%')
    .width('100%')
  }
}

ImageUtil 代码

ini 复制代码
/**
 * 获取图片的uris
 * @returns
 */
export  function getImageUris(callback:(uris:string[])=>void): void {
  const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
  photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE。
  photoSelectOptions.maxSelectNumber = 100; // 选择媒体文件的最大数目。
  let uris: Array<string> = [];
  const photoViewPicker = new photoAccessHelper.PhotoViewPicker();
  photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
    uris = photoSelectResult.photoUris;
    callback(uris);
    console.info('lsk photo  uris:' + uris);
  }).catch((err: BusinessError) => {
    console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
  })
}

```
/**
 * 获取视频的uris
 * @returns
 */
export  function getVideoUris(callback:(uris:string[])=>void) {
  const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
  photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE; // 过滤选择媒体文件类型为IMAGE。
  photoSelectOptions.maxSelectNumber = 100; // 选择媒体文件的最大数目。
  let uris: Array<string> = [];
  const photoViewPicker = new photoAccessHelper.PhotoViewPicker();
  photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
    uris = photoSelectResult.photoUris;
    callback(uris);
  }).catch((err: BusinessError) => {
    console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
  })
}

/**
 * 获取缩略图uri
 */
export function getThumbnailJpgURI(sourceUri:string,modifiedDate:number,path?:string) :string{
  return `${sourceUri}?timestampAPP=${modifiedDate}&oper=thumbnail&width=0&height=0&path=${path ?? ''}`;
}
```

demo 显示图

相关推荐
冰冷的bin5 小时前
【Harmony】鸿蒙相机拍照使用简单示例
数码相机·华为·harmonyos
爱笑的眼睛119 小时前
HarmonyOS RemoteWindow远程窗口组件的分布式能力深度解析
华为·harmonyos
爱笑的眼睛1114 小时前
HarmonyOS Badge徽标组件:深入消息提示的实现与优化
华为·harmonyos
爱笑的眼睛1116 小时前
HarmonyOS List组件性能优化:从基础到高级实践
华为·harmonyos
ifeng091818 小时前
HarmonyOS实战项目:打造智能家居控制中心(设备发现与控制)
wpf·智能家居·harmonyos
ifeng091820 小时前
HarmonyOS分布式数据管理——跨设备数据同步实战
harmonyos
ifeng091821 小时前
HarmonyOS实战项目:开发一个分布式新闻阅读客户端
分布式·wpf·harmonyos
小范馆21 小时前
通过 useEventBus 和 useEventCallBack 实现与原生 Android、鸿蒙、iOS 的事件交互
android·ios·harmonyos
爱笑的眼睛111 天前
HarmonyOS Text组件样式定制深度解析:从基础到高级实践
华为·harmonyos