鸿蒙5.0开发【图片上传至服务器】

图片上传

鸿蒙开发中上传图片流程

1.选择相册中的图片

API version 9 [picker]api选择图片

API version 11 [photoAccessHelper]

2.拷贝图片到缓存目录中

[fs] api拷贝图片

3.图片上传

[request.uploadFile()] 实现上传

1.1 准备工作

1.将下面开发好的代码复制到自己的项目中,list中的数据可以换成自己喜欢的照片网络地址

import { fileIo } from '@kit.CoreFileKit'
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError, request } from '@kit.BasicServicesKit';
import { util } from '@kit.ArkTS';
import { image } from '@kit.ImageKit';
import File from '@system.file';

@Entry
@Component
struct FileCopy {
  @State
  list: ResourceStr[] = [
    "https://img0.baidu.com/it/u=2373411163,3695295946&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202005%2F09%2F20200509082358_QC4tG.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233159&t=7505fc6da6991d423f9165a19aa1edf1",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fci.xiaohongshu.com%2F37f5ca53-0526-7d31-e22c-af01d0336714%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fci.xiaohongshu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233159&t=8897e9bb197bed85dfd091c7772ab98d",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201908%2F15%2F20190815105853_4xB5V.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233159&t=97d2c31c5fae9e0da8dca20b0a5104c9",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201811%2F06%2F20181106210452_kjljj.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233159&t=9ded8a355b5964fee9fa1c833f9795cc",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201809%2F30%2F20180930235959_VCFPn.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233159&t=25320cd1095d6bd3c80800f3f71899b3",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201810%2F28%2F20181028130215_bwthn.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233159&t=d8ac6dc26891d1b4610b8a155c892ccb",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fci.xiaohongshu.com%2F01028n0169bn5d32o6q011c1ytm0lzw63a%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fci.xiaohongshu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233159&t=2f9d2e17f7ebb0ad354140da84c2ef6f",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201810%2F12%2F20181012013627_CLjxR.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233159&t=a24e31dc1a5aa5ee844f9aff882b07c3",
    "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fea86243a-a102-49d3-90e5-f48d3b909b94%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1727233295&t=68ab736b45432a12defeaabf237e3ba7"
  ]

  // 下载到沙箱
  async downLoadImages() {
    let arr: string[] = []
    const allTasks = this.list.map(item => {
      let filePath = getContext().cacheDir + '/' + util.generateRandomUUID() + '.jpg'
      arr.push(filePath)
      return new Promise<boolean>((resolve, reject) => {
        request.downloadFile(getContext(), {
          url: item as string,
          filePath
        }).then(task => {
          task.on("complete", () => {
            resolve(true)
          })
          task.on("fail", () => {
            reject(false)
          })
        })
      })
    })
    await Promise.all(allTasks)
    return arr

  }

  async getFileBuffer(filePath: string): Promise<ArrayBuffer> {
    try {
      const imageSource = image.createImageSource(filePath)
      let imagePackerApi = image.createImagePacker();
      let buffer = await imagePackerApi.packing(imageSource, {
        quality: 100,
        format: 'image/jpeg'
      })
      return buffer
    } catch (err) {
      let error: BusinessError = err as BusinessError;
      console.error(`read file failed, errCode:${error.code}, errMessage:${error.message}`);
      return Promise.reject(err)
    }
  }

  // 保存沙箱图片到相册
  async saveImgToAssets() {
    try {
      const allImages = await this.downLoadImages()
      let index = 0
      while (index < allImages.length) {
        let context = getContext();
        let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
        // Creating a Media File
        let uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
        // Open the created media file and read the local file and convert it to ArrayBuffer for easy filling.
        let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
        const buffer = await this.getFileBuffer(allImages[index])
        // Write the read ArrayBuffer to the new media file.
        let writeLen = await fileIo.write(file.fd, buffer);
        await fileIo.close(file);
        index++
      }
      promptAction.showToast({ message: '下载成功' })

    } catch (err) {
      AlertDialog.show({ message: err.message })
    }
  }

  build() {
    Column({ space: 10 }) {
      Row() {
        SaveButton()
          .onClick((event, result: SaveButtonOnClickResult) => {
            if (result === SaveButtonOnClickResult.SUCCESS) {
              this.saveImgToAssets()
            }
          })
      }
      .justifyContent(FlexAlign.Center)
      .width('100%')

      GridRow({ columns: 2 }) {
        ForEach(this.list, (item: string) => {
          GridCol() {
            Image(item)
              .height(150)
              .height(150)
              .borderRadius(4)
          }
          .margin({
            top: 10
          })
        })
      }

    }

  }
}

2.运行代码,将图片下载到模拟器相册中

1

3.打开相册即可看到刚刚下载好的图片

2

1.2 选择图片

API version 9

import { picker } from '@kit.CoreFileKit'
@Entry
@Component
struct Index {
  async selectImg(){
    //1. 创建参数对象
    const opts = new picker.PhotoSelectOptions() // 创建参数对象
    opts.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE // 设置MIME类型
    opts.maxSelectNumber = 1 // 设置最大选择数量
    //2. 创建选择器对象
    const photoPicker = new picker.PhotoViewPicker()  // 创建选择器对象
    let photos = await photoPicker.select(opts) // 选择图片
    AlertDialog.show({
        message:JSON.stringify(photos)
    })
  }
  build() {

    Column() {
      Button('选择系统相册图片')
        .onClick(()=>{
         this.selectImg()

        })
    }
    .width('100%')
    .height('100%')
  }
}

API version 11

import { photoAccessHelper } from '@kit.MediaLibraryKit'
@Entry
@Component
struct Index {
  async selectImg(){
    // 1. 创建参数对象
    const opts = new photoAccessHelper.PhotoSelectOptions() // 创建参数对象
    opts.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE // 设置MIME类型
    opts.maxSelectNumber = 1 // 设置最大选择数量
    // 2. 创建选择器对象
    const photoPicker = new photoAccessHelper.PhotoViewPicker() // 创建选择器对象
    const photos = await photoPicker.select(opts) // 选择图片
    return photos.photoUris[0]  // 返回图片路径

  }
  build() {

    Column() {
      Button('选择系统相册图片')
        .onClick(()=>{
         this.selectImg()

        })
    }
    .width('100%')
    .height('100%')
  }
}

运行结果

3

1.3 拷贝图片到缓冲目录

import { photoAccessHelper } from '@kit.MediaLibraryKit'
import fs from '@ohos.file.fs';
@Entry
@Component
struct Index {
  async selectImg(){
    // 1. 创建参数对象
    const opts = new photoAccessHelper.PhotoSelectOptions() // 创建参数对象
    opts.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE // 设置MIME类型
    opts.maxSelectNumber = 1 // 设置最大选择数量
    // 2. 创建选择器对象
    const photoPicker = new photoAccessHelper.PhotoViewPicker() // 创建选择器对象
    const photos = await photoPicker.select(opts) // 选择图片
    return photos.photoUris[0] // 返回图片路径
  }
  build() {

    Column() {
      Button('选择系统相册图片')
        .onClick(async ()=>{
          // 获取到系统相册图片的url地址
          let systemPhotoImagePath = await this.selectImg() // 选择图片
          let cacheDir = getContext().cacheDir // 获取缓存目录
          let type = 'jpg' // 设置图片类型
          let finename = Date.now() + '.' + type // 设置图片名称
          let fullPath = cacheDir + '/' + finename // 设置图片路径
          const file = fs.openSync(systemPhotoImagePath,fs.OpenMode.READ_ONLY) // 打开图片

          fs.copyFileSync(file.fd, fullPath) // 复制图片
          AlertDialog.show({
            message:'成功拷贝图片' + fullPath
          })

        })
    }
    .width('100%')
    .height('100%')
  }
}

运行截图

5

通过下图可以发现,我们已经将图片拷贝到了缓冲目录下 6

1.4 上传文件

使用 request.uploadFile()来上传文件到服务器

使用[request.uploadFile()]来上传图片,需 [声明权限] [ohos.permission.INTERNET]

[request.uploadFile()]只支持读取应用程序缓存中的图片来完成上传

import { photoAccessHelper } from '@kit.MediaLibraryKit'
import fs from '@ohos.file.fs';
import { request } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  async selectImg(){
    // 1. 创建参数对象
    const opts = new photoAccessHelper.PhotoSelectOptions() // 创建参数对象
    opts.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE // 设置MIME类型
    opts.maxSelectNumber = 1 // 设置最大选择数量
    // 2. 创建选择器对象
    const photoPicker = new photoAccessHelper.PhotoViewPicker() // 创建选择器对象
    const photos = await photoPicker.select(opts) // 选择图片
    return photos.photoUris[0] // 返回图片路径
  }
  build() {

    Column() {
      Button('上传图片')
        .onClick(async ()=>{
          // 获取到系统相册图片的url地址
          let systemPhotoImagePath = await this.selectImg() // 选择图片
          let cacheDir = getContext().cacheDir // 获取缓存目录
          let filetype = 'jpg' // 设置图片类型
          let finename = Date.now() + '.' + filetype // 设置图片名称
          let fullPath = cacheDir + '/' + finename // 设置图片路径
          const file = fs.openSync(systemPhotoImagePath,fs.OpenMode.READ_ONLY) // 打开图片

          fs.copyFileSync(file.fd, fullPath) // 复制图片
          // 1. 完成图片上传并获得上传对象
          let uploader = await request.uploadFile(getContext(),{ // 上传图片
            url:'https://hmajax.itheima.net/api/uploadimg', // 请求地址
            method:'POST', // 请求方式
            header:{ 'Content-Type': 'multipart/form-data' }, // 请求头
            files:[{ // 上传文件
              filename:finename, // 文件名
              type:filetype, // 文件扩展名
              name:'img', // 接口参数名
              uri:`internal://cache/${finename}` // 缓存目录中的要上传给服务器的图片路径
            }],
            data:[]
          })
          // 2. 监控上传进度
          uploader.on('progress', (uploadSize, totalSize) => {
            // uploadSize: 已上传的文件大小
            // totalSize: 文件总大小
            console.log('上传进度--->', uploadSize, totalSize)
          })

          // 3. 监控上传错误
          uploader.on('fail', (err) => {
            console.log('上传错误--->', JSON.stringify(err))
          })

          //   4. 获取服务器返回来的数据
          uploader.on('headerReceive',(res)=>{
            console.log('上传结果--->', JSON.stringify(res['body']))
          })
        })
    }
    .width('100%')
    .height('100%')
  }
}

运行结果

7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值