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

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

  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

  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

拷贝文件

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

  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等

  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即可完成对应下载功能

  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}`)
    }
  }

相关推荐

  1. Harmonyos Next——图片下载

    2024-06-06 11:46:01       9 阅读
  2. qt 实现 ftp 下载

    2024-06-06 11:46:01       34 阅读
  3. SpringMVC-文件下载

    2024-06-06 11:46:01       35 阅读
  4. FTP文件的下载

    2024-06-06 11:46:01       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-06 11:46:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-06 11:46:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-06 11:46:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-06 11:46:01       18 阅读

热门阅读

  1. WPF 委托

    2024-06-06 11:46:01       8 阅读
  2. Gin入门

    Gin入门

    2024-06-06 11:46:01      8 阅读
  3. ffmpeg常用命令

    2024-06-06 11:46:01       7 阅读
  4. Yolov10环境配置+训练自己数据集(Windows10)

    2024-06-06 11:46:01       8 阅读
  5. Life perception 4

    2024-06-06 11:46:01       7 阅读
  6. python 编写登录界面

    2024-06-06 11:46:01       7 阅读
  7. pandas不要存储excel

    2024-06-06 11:46:01       8 阅读
  8. 深度学习中域适应的简要概述

    2024-06-06 11:46:01       7 阅读
  9. css实现不同设备适配

    2024-06-06 11:46:01       6 阅读