鸿蒙HarmonyOS NEXT开发:鸿蒙应用中图片上传流程解析,从图库中、用户拍照(拉起相机)获取照片
图片上传,图库、拍照获取照片。无论采用哪种方式上传图片,都需要先把用户选择的图片放到应用的沙箱中,再进行上传操作。不同方式的主要区别在于选择照片的形式。
·
一、总体流程概述
无论采用哪种方式上传图片,都需要先把用户选择的图片放到应用的沙箱中,再进行上传操作。不同方式的主要区别在于选择照片的形式。
二、不同方式选择照片
(一)拍照拿取照片
代码实现
const pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(getContext(this),
[cameraPicker.PickerMediaType.PHOTO], {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
});
if(pickerResult.code === -1) return
const uri = pickerResult.resultUri
参数解释
- 参数 1:上下文(
getContext(this)) - 参数 2:拍摄类型(拍照、摄影),以数组形式传入,这里选择了拍照(
cameraPicker.PickerMediaType.PHOTO) - 参数 3:配置信息,包括摄像头位置(这里选择后摄
camera.CameraPosition.CAMERA_POSITION_BACK)
拍照结束后,从pickerResult对象中获取相关信息:
resultUri:照片路径code:成功与否的标志,0表示成功,-1表示失败
(二)图库拿取照片
代码实现
// 先创建照片选择器
const options = new photoAccessHelper.PhotoViewPicker()
// 打开图库选择
const photo = await options.select({MIMEType:photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE, maxSelectNumber:1})
// 返回一个数组,无长度则代表没选
if(photo.photoUris.length==0) return
const uri = photo.photoUris[0]
步骤解释
- 首先创建照片选择器(
new photoAccessHelper.PhotoViewPicker()) - 然后通过
select方法打开图库选择,传入选择照片配置,包括限制选择图片类型(photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE)和最多选择数量(maxSelectNumber:1) - 从返回结果
photo中获取选择的照片路径,如果返回数组长度为 0,则表示没有选择照片
三、图片上传流程
(一)用只读模式打开,拿到文件描述
const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)
(二)将图片放入沙箱中
需要压缩图片的情况
- 拿到图片源
const imageSource = image.createImageSource(file.fd)
- 创建打包器并开始打包
const imagePacker = image.createImagePacker()
const arrayBuffer = await imagePacker.packing (imageSource, {format: 'image/jpeg', quality: 70});
这里将图片打包成jpeg格式,压缩质量为70(100为无压缩)
- 构建沙箱目录文件路径并写入数据
const newFilePath = `${getContext(this).cacheDir}/${file.name}`;
const newFile = fileIo.openSync(newFilePath,
fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
fileIo.writeSync(newFile.fd, arrayBuffer);
不需要压缩图片的情况
直接将图片拷贝到沙箱。参数1为文件描述符,参数2为沙箱目录文件路径。
fileIo.copyFileSync( file.fd,`${getContext(this).cacheDir}/${file.name}`)
此时已经将图片文件拷贝到沙箱中。
(三)调用接口上传
使用request.uploadFile上传
- 上传代码
const task = await request.uploadFile(context, {
// 后端请求地址
url: 'xxxxxxx'
// 请求头信息 类型、token......
header: {
'content - type': 'multipart/form - data',
Authorization: `xxxx`
},
// 请求类型
method: http.RequestMethod.POST,
// 图片信息
files: [{
// 上传给后端的名字
filename: `${file.name}`,
// 沙箱路径
uri: `internal://cache/${file.name}`,
// 和后端Body一致
name: 'file',
// 照片类型(后缀)
type: `${file.name.split('.')[file.name.split('.').length - 1]}`
}],
// 请求的表单数据
data: []
})
- 监听结果
task.on('fail', () => {
AlertDialog.show({ message: '上传失败' })
})
task.on('complete', async () => {
AlertDialog.show({ message: '上传成功' })
})
task.on('progress', (async (uploadedSize: number, totalSize: number) => {
promptAction.showToast({message:上传进度:(uploadedSize/totalSize*100).toFixed(2)+' %'})
}))
使用axios上传
- 创建
FormData对象并添加数据
const formData = new FormData();
formData.append('file', `internal://cache/${file.name}`);
- 上传代码
const res = await axiosRequest({
url:'xxxxx',
data:formData,
method:'post',
context:getContext(this),
headers:{"Content - Type":'multipart/form - data'},
onUploadProgress:(event)=>{ //上传进度
event.loaded // 当前
event.total // 总 }
})
(四)上传完成释放相关资源
fileIo.close(file.fd)
fileIo.close(newFile.fd)
通过以上步骤,我们可以在鸿蒙应用中实现完整的图片上传功能,无论是拍照上传、用户操作上传还是从图库中上传,都可以遵循这一流程来确保图片能够安全、高效地传输到后端服务器。
完整流程图

更多推荐


所有评论(0)