何小豆儿在此 发表于 2025-2-17 05:47:07

【HarmonyOS Next】图片选择方案

配景

封装一个选择图片和调用照相相机的按钮,展示api13下选择图片和调用相机,可以使用不申请用户权限的方式,举行图片的选择和修改。但是,目前方案并未包罗上传图片生存的功能,仅提供图片选择或者照相后,图片展示的一种方案。
https://i-blog.csdnimg.cn/direct/f2f6b625356c46599278f90e5ff7f52e.gif#pic_center
项目架构

https://i-blog.csdnimg.cn/direct/4efb9eff6df74d5284ccb69f2e847d16.png#pic_center


[*]Common :公共操作类存放文件夹
[*]PromptActionClass:全局弹窗操作类
[*]components:公共弹窗组件文件夹
[*]SelectImageDialog:选择图片弹窗组件
[*]pages->Index:入口界面
紧张方法解析

调用相机照相



[*]添加camera, cameraPicker的外部引用
import { camera, cameraPicker } from '@kit.CameraKit';


[*]使用cameraPicker的pick方法实现安全调用设备相机,并返回选择结果cameraPicker.PickerResult对象,通过设置cameraPicker.PickerProfile对象属性实现对相机的初始化属性设置。
try {
//配置相机设置
let pickerProfile: cameraPicker.PickerProfile = {
    cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK,
};
let result: cameraPicker.PickerResult =
    await cameraPicker.pick(getContext(), ,
      pickerProfile);
if (result.resultCode == 0) {
    await this.UpdateShowImage(result.resultUri);
}
PromptActionClass.CloseDialog();
return true;
} catch (e) {
console.info(e);
return false;
}
访问图库选择图片



[*]添加PromptActionClass的外部引用
import { PromptActionClass } from '../Common/PromptActionClass';


[*]使用photoAccessHelper.PhotoViewPicker对象的select方法,实现安全调用相册并选择图片。通过photoAccessHelper.PhotoSelectOptions对象,对选择方法举行初始化,可以设置默认选择、选择数量、选择范例等。
try {
const photoSelectOpt = new photoAccessHelper.PhotoSelectOptions();
//设置选择类型
photoSelectOpt.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
//选择图片最大数量
photoSelectOpt.maxSelectNumber = 1;
//图片选择器
const photoPicker = new photoAccessHelper.PhotoViewPicker();
const selectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(photoSelectOpt)
let uri: string = "";
if (selectResult.isOriginalPhoto || selectResult.photoUris.length == 0) {
    return false;
}
uri = selectResult.photoUris;
await this.UpdateShowImage(uri);
PromptActionClass.CloseDialog();
return true;
} catch (e) {
console.info(e);
return false;
}
整体代码

Index

import { image } from '@kit.ImageKit';import { photoAccessHelper } from '@kit.MediaLibraryKit';import { fileIo } from '@kit.CoreFileKit';import { PromptActionClass } from '../Common/PromptActionClass';
import { SelectImageDialog } from '../components/SelectImageDialog';import { camera, cameraPicker } from '@kit.CameraKit';
@Entry@ComponentV2struct Index {@Local ShowImage: ResourceStr | PixelMap = $r('app.media.AddImageIcon')aboutToAppear(): void {    PromptActionClass.SetContext(this.getUIContext());    PromptActionClass.SetOptions({      builder: () => {      this.PictureBuilder()      },      alignment: DialogAlignment.Bottom,      cornerRadius: {      topLeft: 20,      topRight: 20,      bottomLeft: 20,      bottomRight: 20      },      height: 154,      width: "90%",    })}build() {    RelativeContainer() {      Button() {      Image(this.ShowImage)          .width("100%")          .borderRadius(20)          .padding(10)      }      .width(120)      .height(120)      .type(ButtonType.Normal)      .backgroundColor(Color.White)      .borderWidth(3)      .borderColor('#592708')      .borderRadius(20)      .id("AddImageBtn")      .alignRules({      middle: { anchor: "__container__", align: HorizontalAlign.Center }      })      .margin({ top: 20 })      .onClick(() => {      PromptActionClass.OpenDialog();      })    }    .height('100%')    .width('100%')}@BuilderPictureBuilder() {    SelectImageDialog({      CancelEvent: async () => {      try {          PromptActionClass.CloseDialog();          return true;      } catch (e) {          console.info(e);          return false;      }      },      TakePictureEvent: async () => {      try {          //设置相机设置          let pickerProfile: cameraPicker.PickerProfile = {            cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK,          };          let result: cameraPicker.PickerResult =            await cameraPicker.pick(getContext(), ,            pickerProfile);          if (result.resultCode == 0) {            await this.UpdateShowImage(result.resultUri);          }          PromptActionClass.CloseDialog();          return true;      } catch (e) {          console.info(e);          return false;      }      },      SelectedPictureEvent: async () => {      try {          const photoSelectOpt = new photoAccessHelper.PhotoSelectOptions();          //设置选择范例          photoSelectOpt.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;          //选择图片最大数量          photoSelectOpt.maxSelectNumber = 1;          //图片选择器          const photoPicker = new photoAccessHelper.PhotoViewPicker();          const selectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(photoSelectOpt)          let uri: string = "";          if (selectResult.isOriginalPhoto || selectResult.photoUris.length == 0) {            return false;          }          uri = selectResult.photoUris;          await this.UpdateShowImage(uri);          PromptActionClass.CloseDialog();          return true;      } catch (e) {          console.info(e);          return false;      }      }    })}async UpdateShowImage(uri: string) {    let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY)    const imageSourceApi = image.createImageSource(file.fd);    let map: PixelMap = await imageSourceApi.createPixelMap();    this.ShowImage = map;}} PromptActionClass

import { promptAction } from "@kit.ArkUI";
import { BusinessError } from "@kit.BasicServicesKit";

/**
* 弹窗操作类
*/
export class PromptActionClass {
/**
   *展示界面的ID集合
   */
private static ShowIDArray: number[] = [];
static Context: UIContext;
/**
   * 弹窗界面设置
   */
static Options: promptAction.CustomDialogOptions;

static SetContext(context: UIContext) {
    PromptActionClass.Context = context;
}

static SetOptions(options: promptAction.CustomDialogOptions) {
    PromptActionClass.Options = options;
}

/**
   * 弹窗
   */
static OpenDialog() {
    if (PromptActionClass.Options) {
      PromptActionClass.Context.getPromptAction()
      .openCustomDialog(PromptActionClass.Options)
      .then((id: number) => {
          PromptActionClass.ShowIDArray.push(id);
          console.info('弹窗已打开')
      })
      .catch((error: BusinessError) => {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`弹窗失败,错误代码是:${code}, message 是 ${message}`);
      })
    }
}

/**
   * 关闭弹窗
   */
static CloseDialog() {
    if (PromptActionClass.ShowIDArray.length != 0) {
      try {
      PromptActionClass.Context.getPromptAction()
          .closeCustomDialog(PromptActionClass.ShowIDArray)
      console.info('成功关闭弹窗.')
      } catch {
      (error: BusinessError) => {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`弹窗关闭失败,错误代码:${code}, message 是 ${message}`);
      }
      }
    }
}
}
SelectImageDialog

@ComponentV2
export struct SelectImageDialog {
@Event TakePictureEvent: () => Promise<boolean> = async () => {
    return false;
}
@Event SelectedPictureEvent: () => Promise<boolean> = async () => {
    return false;
}
@Event CancelEvent: () => Promise<boolean> = async () => {
    return false;
}

build() {
    RelativeContainer() {
      Button("拍照")
      .type(ButtonType.Normal)
      .width("100%")
      .id("TakePictureBtn")
      .backgroundColor("#ffffff")
      .height(50)
      .fontColor("#343434")
      .alignRules({
          bottom: { anchor: "SelectedPictureBtn", align: VerticalAlign.Top }
      })
      .onClick(async () => {
          await this.TakePictureEvent();
      })
      Button("从相册中选择")
      .type(ButtonType.Normal)
      .width("100%")
      .height(50)
      .id("SelectedPictureBtn")
      .backgroundColor("#ffffff")
      .fontColor("#343434")
      .borderWidth({ bottom: 2, top: 2 })
      .borderColor("#f6f6f6")
      .alignRules({
          center: { anchor: "__container__", align: VerticalAlign.Center }
      })
      .onClick(async () => {
          await this.SelectedPictureEvent();
      })

      Button("取消")
      .width("100%")
      .type(ButtonType.Normal)
      .height(50)
      .backgroundColor("#ffffff")
      .fontColor("#aeaeae")
      .alignRules({
          top: { anchor: "SelectedPictureBtn", align: VerticalAlign.Bottom }
      })
      .onClick(async () => {
          await this.CancelEvent();
      })
    }
    .height("100%")
    .width("100%")
}
}
图片资源

从绑定资源中下载
代码文件下载

ImageSelectDemo: 图片选择博客代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【HarmonyOS Next】图片选择方案