• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

wkin

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

鸿蒙app开发·图片上传功能

功能可用待完善

图片上传分为几个步骤:使用图库选择器选中图片的uri、对图片进行压缩/格式转换(可无)、将图片上传到沙箱中、利用request模块上传到远程。

注意:由于沙箱机制,无法直接对系统图库进行操作,需用只读方式进行获取进行后续操作。

以实现功能:图片获取、压缩图片,图片打包,图片上传

图片获取:

/*
获取图片,
使用相册管理模块获取图片和视频资源,并返回图片的uri
*/
export async function selectIMG(): Promise<string> {
  try {
    // 1. 建图片选择配置选项创
    let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();

    // 设置MIME类型为图片类型(限制只能选择图片)
    PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;

    // 设置最大选择数量为5张
    PhotoSelectOptions.maxSelectNumber = 1;

    // 2. 创建图片选择器实例
    let photoPicker = new photoAccessHelper.PhotoViewPicker();

    // 3. 调用选择方法并处理结果
    let res = await photoPicker.select(PhotoSelectOptions)
    //返回获取第一张图片的uri
    return res.photoUris[0]
  }catch (error) {
    console.error(`PhotoViewPicker failed with err: ${JSON.stringify(error)}, ${JSON.stringify(error)}`);
    return ''
  }
}

压缩图片:

/*
图片打包:
使用图片打包器类选择图片,并可选择是否自定义压缩样式
* */
export async function reduceIMG(uri:string,imgOptions?:image.PackingOption):Promise<ArrayBuffer>{
  //以只读的方式读取数据并转成数据流
  let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)
  const imageSourceApi = image.createImageSource(file.fd);
  // 图片打包器类实例化
  const picture = image.createImagePacker()
  // 打包配置参数
  const options: image.PackingOption = imgOptions??{
    format: "image/jpeg",
    quality: 50
  }
  //返回打包好的图片数据流对象
  return await picture.packToData(imageSourceApi, options)
}

图片入箱:

/*
图片入沙箱
将操纵后的图片写入(仅可写)沙箱目录,无操作直接copy,入上下文中,无返回(uri的类型可加)
* */
export function inputSandbox(context:Context,uri:ArrayBuffer|string){
  //定义沙箱目录
  let fileDir = `${context.cacheDir}/test.jpg`
    //写入到沙箱目录
  if(typeof uri === 'string'){
    let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)
    fileIo.copyFileSync(file.fd, fileDir)
  }else if(typeof uri === 'object'){
    //开启沙箱子目录得写入权限
    const newfileDir = fileIo.openSync(fileDir, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE)
    fileIo.writeSync(newfileDir.fd, uri)
    fileIo.closeSync(newfileDir.fd)
  }
}

图片上传

/*
图片上传
利用request模块上传上下文沙箱里面的图片
*/
export async function putIMGOffHttp(httpUrl: string, context: Context): Promise<string|object> {
  try {
    const res2 = await request.uploadFile(context, {
      url: httpUrl,
      header: {
        ContentType: 'multipart/form-data'
      },
      method: http.RequestMethod.POST,
      files: [
        {
          filename: 'text.jpg',
          name: 'img',
          uri: 'internal://cache/test.jpg',
          type: 'jpg'
        }
      ],
      data: []
    });

    // 用 Promise 包装监听回调
    return await new Promise<string|object>((resolve, reject) => {
      res2.on('complete', (response) => {
        // 上传成功
        // AlertDialog.show({ message: `上传成功${JSON.stringify(response)}`, alignment: DialogAlignment.Center });
        // resolve(response as T);
      });

      res2.on('fail', (error) => {
        AlertDialog.show({ message: '上传失败', alignment: DialogAlignment.Center });
        reject(error.toString());
      });

      res2.on('headerReceive', (res) => {
        // AlertDialog.show({
        //   message: 'headerReceive' + JSON.stringify(res),
        //   alignment: DialogAlignment.Center
        // });
        resolve(res);
      });

      res2.on('progress', (uploadedSize: number, totalSize: number) => {
        console.info("upload totalSize:" + totalSize + "  uploadedSize:" + uploadedSize);
      });
    });

  } catch (err) {
    AlertDialog.show({ message: 'err' + JSON.stringify(err), alignment: DialogAlignment.Center })
    return err;
  }
}

简单使用:

let uri = await selectIMG()//获取图片uri
let imgurl = await reduceIMG(uri)//压缩图片返回数据流(可无)
inputSandbox(getContext(this),imgurl)//传入修改后的图片数据流
//inputSandbox(getContext(this),uri)//直接传入
let res  = await let res = await putIMGOffHttp('https://hmajax.itheima.net/api/uploadimg',getContext(this))//发送到服务器接口

posted on 2025-04-10 16:50  带头大哥d小弟  阅读(37)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3