鸿蒙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))//发送到服务器接口
浙公网安备 33010602011771号