HarmonyOS 头像修改功能

头像修改可以选择拍照和相册选择照片,然后进行裁剪,拿到相对应的图片设置为头像。

HarmonyOS
2024-12-25 15:52:09
523浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
zbw_apple

头像修改可以选择拍照和相册选择照片,可以参考如下demo,权限申请需要在module.json5文件里配置:

import { BusinessError } from '@kit.BasicServicesKit';
import { abilityAccessCtrl, common, PermissionRequestResult, Permissions, Want } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';
import { fileUri, picker } from '@kit.CoreFileKit';
import fs from '@ohos.file.fs';

const TAG = '[Index]';

@Entry
@Component
struct Index {
  @State path: string = '';
  @State isVideo: boolean = false;

  private context = getContext(this) as common.UIAbilityContext;
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({
      cancel: () => {
        this.onCancel()
      },
      takephoto: () => {
        this.onTakePhoto()
      },
      photoalbums: () => {
        this.onPhotoAlbums()
      },
    }),
  })

  build() {
    Row() {
      Column() {
        if (!this.isVideo && this.path) {
          Image(this.path)
            .width(50)
            .height(50)
            .borderRadius(35)
            .objectFit(ImageFit.Auto)
            .onClick(async () => {
              //权限申请+头像编辑实现
              this.ApplyForPermissions();
            })
        } else {
          Image($r('app.media.startIcon'))
            .width(50)
            .height(50)
            .borderRadius(35)
            .objectFit(ImageFit.Auto)
            .onClick(async () => {
              //权限申请+头像编辑实现
              this.ApplyForPermissions();
            })
        }
      }
      .width('100%')
    }
    .height('100%')
  }

  onCancel() {
    console.info('Callback when the onCancel button is clicked')
  }

  onTakePhoto() {
    console.info('Callback when the onTakePhoto button is clicked')
    //拉起系统相机拍照
    this.startAbility('ohos.want.action.imageCapture', 'com.huawei.flexlaout.myapplication');
  }

  async onPhotoAlbums() {
    console.info('Callback when the onPhotoAlbums button is clicked')
    //从相册选择照片
    await this.photoPickerGetUri().then(value => {
      this.isVideo = false;
      this.path = value;
    });
  }

  async photoPickerGetUri(): Promise<string> {
    let uris: Array<string> = [];
    try {
      let PhotoSelectOptions = new picker.PhotoSelectOptions();
      PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
      PhotoSelectOptions.maxSelectNumber = 1;
      let photoPicker = new picker.PhotoViewPicker();
      await photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: picker.PhotoSelectResult) => {
        console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' +
        JSON.stringify(PhotoSelectResult));
        uris = PhotoSelectResult.photoUris;
      }).catch((err: BusinessError) => {
        console.error('PhotoViewPicker.select failed with err: ' + JSON.stringify(err));
      });
    } catch (error) {
      let err = error as BusinessError;
      console.error('PhotoViewPicker failed with err: ' + err.message);
    }
    return uris[0].toString();
  }

  ApplyForPermissions() {
    let permissions: Array<Permissions> = [
      'ohos.permission.WRITE_IMAGEVIDEO',
      'ohos.permission.READ_IMAGEVIDEO',
    ];
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
    atManager.requestPermissionsFromUser(this.context, permissions).then((data: PermissionRequestResult) => {
      let grantStatus: Array<number> = data.authResults;
      let length: number = grantStatus.length;
      for (let i = 0; i < length; i++) {
        if (grantStatus[i] != 0) {
          // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
          return;
        }
      }
      console.info(`${TAG} Success to request permissions from user. authResults is ${grantStatus}.`);
      //弹框让客户选择头像是通过拍照获取还是从相册选择,同时还有取消按钮
      this.dialogController.open()
    }).catch((err: BusinessError) => {
      console.error(`${TAG} Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
    })
  }

  //拉起系统相机
  startAbility(action: string, bundleName: string) {
    let want: Want = {
      action: action,
      parameters: {
        // 拍照完成后返回的应用BundleName
        callBundleName: bundleName,
        supportMultiMode: false
      }
    };
    try {
      this.context.startAbilityForResult(want, (err: BusinessError, result: common.AbilityResult) => {
        if (err.code) {
          // 处理业务逻辑错误
          console.error(TAG, `startAbilityForResult failed, code is ${err.code}, message is ${err.message}`);
          return;
        }
        let uri: string = result?.want?.parameters?.resourceUri as string;
        // 执行正常业务
        console.info(TAG, `Succeeded in starting ability for result. Data is ${JSON.stringify(result)}, uri is ${uri}`);
        if (uri) {
          // 保存到本地
          this.save2Local(uri);
        } else {
          promptAction.showToast({ message: '拍摄失败' })
        }
      });
    } catch (err) {
      let error = err as BusinessError;
      console.error(TAG, `startAbilityForResult failed, err is ${JSON.stringify(error)}`);
      promptAction.showToast({ message: '拍摄失败' })
    }
  }

  save2Local(uri: string) {
    try {
      let file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
      let prefix = uri.substring(uri.lastIndexOf('.') + 1);
      let tempFileName = getContext(this).filesDir + '/' + new Date().getTime() + '.' + prefix;
      let tempFile = fs.openSync(tempFileName, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
      fs.copyFileSync(file.fd, tempFile.fd);
      this.path = fileUri.getUriFromPath(tempFileName);
      this.isVideo = (prefix == 'mp4' || prefix == 'MP4');
      console.info(TAG, `resolve2Sandbox successful.`);
      promptAction.showToast({ message: '拍摄成功' })
    } catch (err) {
      let error = err as BusinessError;
      console.error(TAG, `resolve2Sandbox failed, err is ${JSON.stringify(error)}`);
    }
  }
}

@CustomDialog
struct CustomDialogExample {
  cancel?: () => void
  takephoto?: () => void
  photoalbums?: () => void
  controller: CustomDialogController
  build() {
    Column() {
      Button('拍照')
        .onClick(() => {
          this.controller.close()
          if (this.takephoto) {
            this.takephoto()
          }
        }).backgroundColor(0xffffff).fontColor(Color.Black)
      Button('从相册选择')
        .onClick(() => {
          this.controller.close()
          if (this.photoalbums) {
            this.photoalbums()
          }
        }).backgroundColor(0xffffff).fontColor(Color.Black)
      Button('取消')
        .onClick(() => {
          this.controller.close()
          if (this.cancel) {
            this.cancel()
          }
        }).backgroundColor(0xffffff).fontColor(Color.Black)
    }
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
分享
微博
QQ
微信
回复
2024-12-25 18:49:20


相关问题
HarmonyOS如何实现头像选择功能
1713浏览 • 1回复 待解决
HarmonyOS头像上传问题
1499浏览 • 1回复 待解决
HarmonyOS list数据刷新,头像闪烁
591浏览 • 1回复 待解决
HarmonyOS头像生成的Demo
568浏览 • 1回复 待解决
选择头像Button的实现
1294浏览 • 1回复 待解决
HarmonyOS 如何较好的实现圆形头像
903浏览 • 1回复 待解决
来电横幅通知头像无法显示
2406浏览 • 1回复 待解决
HarmonyOS 华为账号登录获取头像和昵称
1031浏览 • 1回复 待解决
进入相册或拍照选择图片做头像
14477浏览 • 2回复 已解决
关于群聊微信朋友头像的问题!
7745浏览 • 2回复 待解决
使用Account Kit 获取用户头像昵称
1153浏览 • 1回复 待解决
取消Account Kit 获取用户头像昵称授权
1379浏览 • 1回复 待解决
我现在想做一个用户圆形头像功能
850浏览 • 1回复 待解决
键值型数据库能存用户头像吗?
347浏览 • 1回复 待解决
HarmonyOS SegmentButton控件修改高度
581浏览 • 1回复 待解决
HarmonyOS如何修改气泡位置
725浏览 • 1回复 待解决