HarmonyOS鸿蒙next 上传图片前压缩图片 修改图片尺寸

HarmonyOS鸿蒙next 上传图片前压缩图片 修改图片尺寸可以使用pixelMap对象实现

pixelMap缩放图片 改变图片尺寸

scaleImg() {
    // 宽为原来的0.5
    // 高为原来的0.5
    this.pixelMap.scale(0.5, 0.5).then(() => {
      this.message = "图片缩放成功"
    })
  }

完整

convertFileUri = (uri: string) => {
    //uri  file://media/Photo/296/IMG_1729581568_269/IMG_20241022_151748.jpg
    fs.open(uri, fs.OpenMode.READ_ONLY).then(async (data) => {

      let context = getContext(this) as Context
      //获取时间戳
      let fileName = Date.now()
      //获取文件后缀名
      let extname = uri.split(".")[1]
      //cacheDir对应的文件路径
      let newDir = context.cacheDir + "/" + fileName + "." + extname
      //对图片进行压缩
      // 1、获取图片对应的PixelMap
      let pixelMap = await this.getPixelMap(data.fd)
      //2、对图片进行压缩
      pixelMap?.scale(0.2,0.2).then(()=>{
         //3、把pixelMap资源保存到newDir里面  https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/image-encoding-V5
        const imagePackerApi = image.createImagePacker();
        let packOpts : image.PackingOption = { format:"image/jpeg", quality:100 };
        imagePackerApi.packing(pixelMap, packOpts).then( (data : ArrayBuffer) => {
          // data 为打包获取到的文件流,写入文件保存即可得到一张图片
          let fileData=fs.openSync(newDir, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
          fs.writeSync(fileData.fd,data)
          this.doUpload(newDir, extname)
        }).catch((error : BusinessError) => {
          console.error('Failed to pack the image. And the error is: ' + error);
        })
      })

    }).catch((err: Error) => {
      this.message = "fsOpen Error message=" + err.message
    })
  }
  // 获取PixelMap
  getPixelMap = async (fd: number) => {
    const imageSourceApi = image.createImageSource(fd);
    if (!imageSourceApi) {
      return;
    }
    let pixelMap = await imageSourceApi.createPixelMap({
      editable: true
    })
    return pixelMap
  }

更多关于HarmonyOS鸿蒙next 上传图片前压缩图片 修改图片尺寸的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙next 上传图片前压缩图片 修改图片尺寸的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


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("文件操作")
  }
}
回到顶部