HarmonyOS鸿蒙next 上传图片前压缩图片 修改图片尺寸 完整代码如下:
import { AppBar } from './widget/AppBar'
import PermissionUtil from '../common/PermissionUtil';
import { Permissions } from '@ohos.abilityAccessCtrl';
import { promptAction } from '@kit.ArkUI';
import { cameraPicker as picker } from '@kit.CameraKit';
import { camera } from '@kit.CameraKit';
import { common } from '@kit.AbilityKit';
import { BusinessError, request } from '@kit.BasicServicesKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import fs from '@ohos.file.fs';
import { image } from '@kit.ImageKit';
//获取context对象
let mContext = getContext(this) as common.Context;
@Builder
export function ImageUploadPageBuilder() {
ImageUploadPage()
}
@Component
struct ImageUploadPage {
@State message: string = 'Hello World';
@State imagePath: string = ""
@State videoPath: string = ""
private pathStack = new NavPathStack()
//相机拍照
takePhoto = async () => {
try {
// 创建一个选择器对象,并设置参数
let pickerProfile: picker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
};
// 调用选择器对象,实现拍照
let pickerResult: picker.PickerResult = await picker.pick(mContext,
[picker.PickerMediaType.PHOTO, picker.PickerMediaType.VIDEO], pickerProfile);
console.log("the pick pickerResult is:" + JSON.stringify(pickerResult));
this.convertImgUri(pickerResult.resultUri)
//图片地址
this.imagePath = pickerResult.resultUri
} catch (error) {
let err = error as BusinessError;
console.error(`the pick call failed. error code: ${err.code}`);
}
}
//录制视频
takeVideo = async () => {
try {
// 创建一个选择器对象,并设置参数
let pickerProfile: picker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
};
// 调用选择器对象,实现拍照
let pickerResult: picker.PickerResult = await picker.pick(mContext,
[picker.PickerMediaType.VIDEO], pickerProfile);
console.log("the pick pickerResult is:" + JSON.stringify(pickerResult));
//图片地址
this.videoPath = pickerResult.resultUri
} catch (error) {
let err = error as BusinessError;
console.error(`the pick call failed. error code: ${err.code}`);
}
}
//相册选择图片
pickerPhoto = () => {
try {
// 创建一个选择器对象,并设置参数
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 5;
// 调用选择器对象,实现选择图片
let photoPicker = new photoAccessHelper.PhotoViewPicker();
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' +
JSON.stringify(PhotoSelectResult));
this.imagePath = PhotoSelectResult.photoUris[0]
this.convertImgUri(PhotoSelectResult.photoUris[0])
}).catch((err: BusinessError) => {
console.error(`PhotoViewPicker.select failed with err: ${err.code}, ${err.message}`);
});
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(`PhotoViewPicker failed with err: ${err.code}, ${err.message}`);
}
}
//相册选择视频
pickerVideo = () => {
try {
// 创建一个选择器对象,并设置参数
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE; //视频
PhotoSelectOptions.maxSelectNumber = 5;
// 调用选择器对象,实现选择图片
let photoPicker = new photoAccessHelper.PhotoViewPicker();
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' +
JSON.stringify(PhotoSelectResult));
this.videoPath = PhotoSelectResult.photoUris[0]
this.convertImgUri(PhotoSelectResult.photoUris[0])
}).catch((err: BusinessError) => {
console.error(`PhotoViewPicker.select failed with err: ${err.code}, ${err.message}`);
});
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(`PhotoViewPicker failed with err: ${err.code}, ${err.message}`);
}
}
//相册选择图片和视频
pickerPhotoAndVideo = async () => {
try {
// 创建一个选择器对象,并设置参数
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE; //视频或者图片
PhotoSelectOptions.maxSelectNumber = 5;
// 调用选择器对象,实现选择图片
let photoPicker = new photoAccessHelper.PhotoViewPicker();
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' +
JSON.stringify(PhotoSelectResult));
this.videoPath = PhotoSelectResult.photoUris[0]
}).catch((err: BusinessError) => {
console.error(`PhotoViewPicker.select failed with err: ${err.code}, ${err.message}`);
});
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(`PhotoViewPicker failed with err: ${err.code}, ${err.message}`);
}
}
//检测拍照的权限
checkTakePhotoPermission = async () => {
let permissions: Array<Permissions> = ['ohos.permission.CAMERA']
let hasPermission = await PermissionUtil.checkPermission(permissions)
if (hasPermission) {
this.takePhoto()
} else {
let grantStatus = await PermissionUtil.requestPermission(permissions)
if (grantStatus) {
this.takePhoto()
} else {
//跳转到权限设置的引导页面
PermissionUtil.openPermissionSettings("com.itying.myapplication")
}
}
}
//录制视频的权限
checkTakeVideoPermission = async () => {
let permissions: Array<Permissions> = ['ohos.permission.CAMERA', 'ohos.permission.MICROPHONE']
//检测权限
let hasPermission = await PermissionUtil.checkPermission(permissions)
if (hasPermission) {
this.takeVideo()
} else {
let grantStatus = await PermissionUtil.requestPermission(permissions)
if (grantStatus) {
this.takeVideo()
} else {
//跳转到权限设置的引导页面
PermissionUtil.openPermissionSettings("com.itying.myapplication")
}
}
}
// 获取PixelMap
getPixelMap = async (fd: number) => {
// 1、创建图片源
const imageSourceApi = image.createImageSource(fd);
if (!imageSourceApi) {
return;
}
// 2、创建PixelMap
let pixelMap = await imageSourceApi.createPixelMap({
editable: true
})
return pixelMap
}
/*
目标:
file://media/Photo/229/IMG_1729508435_214/IMG_20241021_185855.jpg 复制到 cache目录 file://com.itying.xxx/data/xxx/cache/xxxxx.png
转换成 `internal://cache/file.txt`
*/
convertImgUri= (uri: string)=> {
fs.open(uri, fs.OpenMode.READ_ONLY).then(async (file) => { //注意async
//context
let context = getContext(this);
let fileName=Date.now() //获取当前时间戳
let extName=uri.split(".")[1]
let newDir=context.cacheDir+"/"+fileName+"."+extName // file://com.itying.xxx/data/xxx/cache/1232141254.jpg
//压缩图片
let pixelMap = await this.getPixelMap(file.fd) //注意await
//编辑 压缩
pixelMap!.scale(0.2, 0.2).then(async () => {
//https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/image-encoding-V5
//把pixelMap转换成newDir中的一个图片
const imagePackerApi = image.createImagePacker();
//图片的质量
let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };
//创建一个图片打包对象 cache文件
let cacheFile= fs.openSync(newDir, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
//把pixelMap转换成 cache文件
imagePackerApi.packToFile(pixelMap, cacheFile.fd, packOpts).then(() => {
// 上传
this.uploadFile(newDir)
}).catch((error : BusinessError) => {
console.error('Failed to pack the image. And the error is: ' + error);
})
});
});
}
// convertImgUri = (uri: string) => {
// fs.open(uri, fs.OpenMode.READ_ONLY).then((file) => {
// //context
// let context = getContext(this);
// let fileName = Date.now() //获取当前时间戳
// let extName = uri.split(".")[1]
// let newDir =
// context.cacheDir + "/" + fileName + "." + extName // file://com.itying.xxx/data/xxx/cache/1232141254.jpg
//
// fs.copyFile(file.fd, newDir).then(async () => {
// let cacheFile = fs.openSync(newDir, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
// // 1、获取图片对应的PixelMap
// let pixelMap = await this.getPixelMap(file.fd)
// pixelMap?.scale(0.2, 0.2).then(() => {
// let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };
// const imagePackerApi = image.createImagePacker();
// imagePackerApi.packToFile(pixelMap, cacheFile.fd, packOpts).then(() => {
// this.uploadFile(newDir)
// // 直接打包进文件
// }).catch((error: BusinessError) => {
// console.error('Failed to pack the image. And the error is: ' + error);
// })
// })
// })
// });
// }
//上传文件
uploadFile = (uri: string) => {
//比如环境路径 file://com.itying.xxx/data/xxx/cache/xxxxx.png
let fileName = uri.split("cache/")[1]
let uploadUri = "internal://cache/" + fileName
let uploadTask: request.UploadTask;
let uploadConfig: request.UploadConfig = {
url: 'https://miapp.itying.com/imgupload', // 需要手动将url替换为真实服务器的HTTP协议地址
header: { 'Accept': '*/*' },
method: "POST",
files: [{
filename: fileName,
name: "himg",
uri: uploadUri,
type: "image/jpeg"
}], // 建议type填写HTTP协议规范的MIME类型
data: [{ name: "uid", value: "123" }, { name: "sign", value: "qwfwqrwqrwqtrwqtqt" }],
};
try {
request.uploadFile(getContext(), uploadConfig).then((data: request.UploadTask) => {
uploadTask = data;
//监听上传进度
uploadTask.on('progress', (uploadedSize: number, totalSize: number) => {
console.info("upload totalSize:" + totalSize + " uploadedSize:" + uploadedSize);
this.message = "upload totalSize:" + totalSize + " uploadedSize:" + uploadedSize
});
uploadTask.on('headerReceive', (headers) => {
console.log(headers["body"])
});
//{"success":"true","path":"public/upload/h0wncqAQLRj6wcMLcQnC8HFE.jpg"}
//通过拼接域名可以访问服务器返回的图片地址 https://miapp.itying.com/public/upload/h0wncqAQLRj6wcMLcQnC8HFE.jpg
}).catch((err: BusinessError) => {
console.error(`Failed to request the upload. Code: ${err.code}, message: ${err.message}`);
});
} catch (err) {
console.error(`Failed to request the upload. err: ${JSON.stringify(err)}`);
}
}
build() {
NavDestination() {
Scroll() {
Column() {
Text(this.message).fontSize(20)
Button() {
Text("相机拍照")
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}.onClick(this.checkTakePhotoPermission).margin({
top: 20
}).width("80%")
.height(50)
Button() {
Text("录制视频")
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}.onClick(this.checkTakeVideoPermission).margin({
top: 20
}).width("80%")
.height(50)
Button() {
Text("录制视频")
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}.onClick(this.checkTakeVideoPermission).margin({
top: 20
}).width("80%")
.height(50)
Button() {
Text("相册选择图片")
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}.onClick(this.pickerPhoto).margin({
top: 20
}).width("80%")
.height(50)
Button() {
Text("相册选择视频")
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}.onClick(this.pickerVideo).margin({
top: 20
}).width("80%")
.height(50)
Button() {
Text("相册选择图片/视频")
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}.onClick(this.pickerPhotoAndVideo).margin({
top: 20
}).width("80%")
.height(50)
if (this.imagePath) {
Image(this.imagePath)
.width(120)
.height(120)
.backgroundColor(Color.Grey)
.margin({ top: 20 })
}
if (this.videoPath) {
Video({
src: this.videoPath
}).width("100%")
.height(300)
.margin({ top: 20 })
}
}
.width('100%')
.justifyContent(FlexAlign.Start)
}
}.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack
}).title("文件操作")
}
}