Harmonyos Next——图片上传与下载

Harmonyos Next------图片上传与下载

图片上传至服务器

描述

从手机相册中选择一张图片,然后上传至服务器

选取图片

在从相册或者拍摄获取的图片之前,需要进行权限申请,其权限为媒体内容读写权限

'ohos.permission.READ_MEDIA' //允许应用读取用户外部存储中的媒体文件信息-用户授权

s'ohos.permission.WRITE_MEDIA' //允许应用读写用户外部存储中的媒体文件信息-用户授权

从相册选择图片

通过picker.PhotoViewPicker()选择相册内容,在选择之前可以设置选择数量、资源类型等。

例如选取其中一张图片,返回的URI格式如下:

file://media/Photo/2/IMG_1713776063_001/screenshot_20240422_165243.jpg

但此格式并不能直接上传至服务器,需要对其进行拷贝,格式转换等操作,将在下节进行阐述。

c 复制代码
  private async openGallery(onSuccess: (uri: string)=> void, onFailed: (error: string)=>void) {
    try {
      let PhotoSelectOptions = new picker.PhotoSelectOptions()
      PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE
      PhotoSelectOptions.maxSelectNumber = 1
      let photoPicker = new picker.PhotoViewPicker()
      photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: picker.PhotoSelectResult) => {
        //file://media/Photo/2/IMG_1713776063_001/screenshot_20240422_165243.jpg
        if (PhotoSelectResult.photoUris.length > 0) {
          onSuccess(PhotoSelectResult.photoUris[0])
        }
      }).catch((err: BusinessError) => {
        LoggerJoy.error('PhotoViewPicker.select failed with err: ' + JSON.stringify(err))
        onFailed(err.message)
      })
    } catch (error) {
      let err: BusinessError = error as BusinessError
      LoggerJoy.error('PhotoViewPicker failed with err: ' + JSON.stringify(err))
      onFailed(err.message)
    }
  }

通过拍摄获取图片

通过cameraPicker.pick打开相机页面,如果完成拍照并点击确认,则会返回如上节一样格式的URI

c 复制代码
  private async openCamera(onSuccess: (uri: string)=> void, onFailed: (error: string)=>void){
    try {
      let pickerProfile: cameraPicker.PickerProfile = {
        cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
      }
      let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(
        getContext(this),
        [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO],
        pickerProfile
      )
      if (pickerResult) {
        onSuccess( pickerResult.resultUri)
      }
    } catch (error) {
      let err = error as BusinessError
      LoggerJoy.error(`the pick call failed. error code: ${err.code}`)
      onFailed(err.message)
    }
  }

将获取的图片上传至服务器

由于上述获取的文件为file开头,外部并不能直接进行访问,可以将其拷贝到APP目录下的沙箱文件中。由于本Demo采用的是系统提供的request.uploadFile,其路径前缀指定为internal://cache/,所有还需在拷贝之后的新路径前加上此前缀,此前缀对应的是临时目录cacheDir

拷贝文件

拷贝之后的文件存放于应用目录下的沙箱文件中

c 复制代码
  private async copyFileToCache(path: string, context: Context): Promise<string>{
    try {
      let file = await fs.open(path, fs.OpenMode.READ_WRITE)
      if (file){
        let dir =  context.cacheDir + '/avatar'
        if (!fs.accessSync(dir)) {
          fs.mkdirSync(dir)
        }
        let newpath = context.cacheDir + `/avatar/hohem${new Date().getTime()}.jpg`
        LoggerJoy.info(`newpath:${newpath}`)
        await fs.copyFile(file.fd, newpath)
        return newpath
      }
      return ''
    } catch (err){
      LoggerJoy.info("applog:open file failed with error message: " + err.message + ", error code: " + err.code)
      return ''
    }
  }

上传图片

在使用request前需要导入对应包

import { BusinessError, request } from '@kit.BasicServicesKit'

拷贝之后的路径格式如下

/data/storage/el2/base/haps/entry/cache/avatar/hohem1713924905931.jpg

然后在其前面添加指定前缀internal://cache/,由于此前缀对应的便是cacheDir目录,所以将拷贝之后的路径前面一部分进行省略,最终得到的路径如下

internal://cache/avatar/hohem1713924905931.jpg

若未对路径进行转换,会出现401-the parameters check fails this is fail path异常错误。

在进行上传时,需根据自己云服务器所配置的接受数据格式进行变化request.UploadConfig,例如是PUT还是POST,是否还需其他头参数,例如id、token等

c 复制代码
  private async uploadFileToCloud(context: Context, uploadUrl: string, path: string, avatar: string, onSuccess: (avatar: string)=> void, onFailed: (error: string) => void){
    let newPath = await this.copyFileToCache(path, context)//---/data/storage/el2/base/haps/entry/cache/avatar/hohem1713924905931.jpg
    newPath = `internal://cache/${newPath.split("cache/")[1]}` //internal://cache/avatar/hohem1713924905931.jpg
    LoggerJoy.info(`newpath:${newPath}`)
    let file: Array<request.File> = [
      {
        name: 'avatarName',
        filename: 'avatarFilename',
        uri: newPath,
        type: 'image'
      }
    ]

    let config: request.UploadConfig = {
      url: uploadUrl,
      method: 'PUT',
      files: file,
      header: {
        'Content-Type': 'application/octet-stream'
      },
      data: []
    }

    try {
      request.uploadFile(
        context,
        config
      ).then((result)=>{
        onSuccess(avatar)
      }).catch((err: BusinessError)=>{
        onFailed(err.message)
      })
    } catch (error) {
      //401-the parameters check fails   this is fail path
      onFailed((error as BusinessError).message)
    }
  }

图片下载

下载图片比上传图片简单的多,依旧使用系统提供的request.downloadFileAPI完成。

例如存在https://xxxxxxx.com/system/202403/1773228028463067136.jpgURL图片资源,

为了减少文件名称冗余和唯一性,我们可以只截取最后一部分做为下载之后的图片名称(1773228028463067136.jpg),然后同样保存到应用目录下的沙箱文件下。

最后调用request.downloadFile即可完成对应下载功能

c 复制代码
  private downloadImages(context: Context,url: string){
    let splits = url.split('/')
    let fileName = splits[splits.length - 1]
    let basePath = context.cacheDir + '/banner' //:/data/storage/el2/base/haps/entry/cache/banner/1773228028463067136.jpg
    this.checkBannerDirExist(basePath) //如果目录不存在,则直接创建目录
    let config: request.DownloadConfig = {
      url: url,
      filePath: `${basePath}/${fileName}`
    }
    try {
      request.downloadFile(context, config, (err: BusinessError, data: request.DownloadTask)=>{
        if (err) {
          //下载失败
          LoggerJoy.info(`write local banner failed:${url}`)
          return
        }
        LoggerJoy.info(`download banner successful:${url}`)
        //下载成功
      })
    } catch (error) {
      LoggerJoy.info(`write local banner failed:${(error as BusinessError).message}`)
    }
  }
相关推荐
ZZZCY20033 分钟前
华为VER系统及CLI命令熟悉
华为
SameX24 分钟前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
Random_index8 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
鸿蒙自习室12 小时前
鸿蒙多线程开发——线程间数据通信对象02
ui·harmonyos·鸿蒙
SuperHeroWu714 小时前
【HarmonyOS】鸿蒙应用接入微博分享
华为·harmonyos·鸿蒙·微博·微博分享·微博sdk集成·sdk集成
期待未来的男孩14 小时前
华为FusionCube 500-8.2.0SPC100 实施部署文档
华为
岳不谢16 小时前
VPN技术-VPN简介学习笔记
网络·笔记·学习·华为
zhangjr057516 小时前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts
诗歌难吟4641 天前
初识ArkUI
harmonyos
SameX1 天前
HarmonyOS Next 设备安全特性深度剖析学习
harmonyos