【HarmonyOS】模仿个人中心头像图片,调用系统相机拍照,从系统相册选择图片和圆形裁剪显示 (二)

本文主要是介绍【HarmonyOS】模仿个人中心头像图片,调用系统相机拍照,从系统相册选择图片和圆形裁剪显示 (二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【HarmonyOS】模仿个人中心头像图片,调用系统相机拍照,从系统相册选择图片和圆形裁剪显示 (二)

Demo效果展示:

在这里插入图片描述

方案思路:

1.修改调用相机的方式,使用cameraKit进行相机的调用,拍照后返回图片url进行处理。
2.裁剪View,使用画布进行取景框的效果展示

手势拖动和放大缩小图片,裁剪计算在第三章进行讲解。

Demo示例代码:

UI主界面


import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { image } from '@kit.ImageKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { router } from '@kit.ArkUI';
import { cameraPicker as picker } from '@kit.CameraKit';
import { camera } from '@kit.CameraKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { CropView } from './CropView';

struct Index {private TAG: string = "imageTest"; mUserPixel: image.PixelMap | undefined = undefined; mTargetPixel: image.PixelMap | undefined = undefined;/*** 拍照获取图片*/private async getPictureFromCamera(){try {let pickerProfile: picker.PickerProfile = {// 相机的位置。cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK};let pickerResult: picker.PickerResult = await picker.pick(getContext(),[picker.PickerMediaType.PHOTO],pickerProfile);console.log(this.TAG, "the pick pickerResult is:" + JSON.stringify(pickerResult));// 成功才处理if(pickerResult && pickerResult.resultCode == 0){await this.getImageByPath(pickerResult.resultUri);}} catch (error) {let err = error as BusinessError;console.error(this.TAG, `the pick call failed. error code: ${err.code}`);}}/*** 相册选择图片*/private async getPictureFromAlbum() {let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;PhotoSelectOptions.maxSelectNumber = 1;let photoPicker = new photoAccessHelper.PhotoViewPicker();let photoSelectResult: photoAccessHelper.PhotoSelectResult = await photoPicker.select(PhotoSelectOptions);let albumPath = photoSelectResult.photoUris[0];console.info(this.TAG, 'getPictureFromAlbum albumPath= ' + albumPath);await this.getImageByPath(albumPath);}/*** 获取图片pixelMap* @param path*/private async getImageByPath(path: string) {console.info(this.TAG, 'getImageByPath path: ' + path);try {// 读取图片为bufferconst file = fs.openSync(path, fs.OpenMode.READ_ONLY);let photoSize = fs.statSync(file.fd).size;console.info(this.TAG, 'Photo Size: ' + photoSize);let buffer = new ArrayBuffer(photoSize);fs.readSync(file.fd, buffer);fs.closeSync(file);// 解码成PixelMapconst imageSource = image.createImageSource(buffer);console.log(this.TAG, 'imageSource: ' + JSON.stringify(imageSource));this.mUserPixel = await imageSource.createPixelMap({});} catch (e) {console.info(this.TAG, 'getImage e: ' + JSON.stringify(e));}}build() {Scroll(){Column() {Text("点击拍照").fontSize(50).fontWeight(FontWeight.Bold).onClick(() => {this.getPictureFromCamera();})Text("相册选择").fontSize(50).fontWeight(FontWeight.Bold).onClick(() => {this.getPictureFromAlbum();})Image(this.mUserPixel).objectFit(ImageFit.Fill).width('100%').aspectRatio(1)Text("图片裁剪").fontSize(50).fontWeight(FontWeight.Bold).onClick(() => {this.cropImage();// router.pushUrl({//   url: "pages/crop"// })})CropView({ mImg: $mUserPixel }).width('100%').aspectRatio(1)Text("裁剪效果").fontSize(50).fontWeight(FontWeight.Bold)Image(this.mTargetPixel).width('100%').aspectRatio(1).borderRadius(200)}.height(3000).width('100%')}.height('100%').width('100%')}private async cropImage(){if(!this.mUserPixel){return;}let cp = await this.copyPixelMap(this.mUserPixel);let region: image.Region = { x: 0, y: 0, size: { width: 400, height: 400 } };cp.cropSync(region);}async copyPixelMap(pixel: PixelMap): Promise<PixelMap> {const info: image.ImageInfo = await pixel.getImageInfo();const buffer: ArrayBuffer = new ArrayBuffer(pixel.getPixelBytesNumber());await pixel.readPixelsToBuffer(buffer);const opts: image.InitializationOptions = {editable: true,pixelFormat: image.PixelMapFormat.RGBA_8888,size: { height: info.size.height, width: info.size.width }};return image.createPixelMap(buffer, opts);}}

CropView 裁剪View


interface LoadResult {width: number;height: number;componentWidth: number;componentHeight: number;loadingStatus: number;contentWidth: number;contentHeight: number;contentOffsetX: number;contentOffsetY: number;
}
export struct CropView {private TAG: string = "CropView";private mRenderingContextSettings: RenderingContextSettings = new RenderingContextSettings(true);private mCanvasRenderingContext2D: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.mRenderingContextSettings); mImg: PixelMap;private onLoadImgComplete = (msg: LoadResult) => {}private onCanvasReady = ()=>{if(!this.mCanvasRenderingContext2D){console.error(this.TAG, "onCanvasReady error mCanvasRenderingContext2D null !");return;}let cr = this.mCanvasRenderingContext2D;// 画布颜色cr.fillStyle = '#AA000000';let height = cr.height;let width = cr.width;cr.fillRect(0, 0, width, height);// 圆形的中心点let centerX = width / 2;let centerY = height / 2;// 圆形半径let radius = Math.min(width, height) / 2 - 100;cr.globalCompositeOperation = 'destination-out'cr.fillStyle = 'white'cr.beginPath();cr.arc(centerX, centerY, radius, 0, 2 * Math.PI);cr.fill();cr.globalCompositeOperation = 'source-over';cr.strokeStyle = '#FFFFFF';cr.beginPath();cr.arc(centerX, centerY, radius, 0, 2 * Math.PI);cr.closePath();cr.lineWidth = 1;cr.stroke();}build() {Stack() {// 黑色底图Row().width("100%").height("100%").backgroundColor(Color.Black)// 用户图Image(this.mImg).objectFit(ImageFit.Fill).width('100%').aspectRatio(1).onComplete(this.onLoadImgComplete)// 取景框Canvas(this.mCanvasRenderingContext2D).width('100%').height('100%').backgroundColor(Color.Transparent).onReady(this.onCanvasReady).clip(true).backgroundColor("#00000080")}.width("100%").height("100%")}
}

这篇关于【HarmonyOS】模仿个人中心头像图片,调用系统相机拍照,从系统相册选择图片和圆形裁剪显示 (二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1121809

相关文章

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

利用Python脚本实现批量将图片转换为WebP格式

《利用Python脚本实现批量将图片转换为WebP格式》Python语言的简洁语法和库支持使其成为图像处理的理想选择,本文将介绍如何利用Python实现批量将图片转换为WebP格式的脚本,WebP作为... 目录简介1. python在图像处理中的应用2. WebP格式的原理和优势2.1 WebP格式与传统

python如何调用java的jar包

《python如何调用java的jar包》这篇文章主要为大家详细介绍了python如何调用java的jar包,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录一、安装包二、使用步骤三、代码演示四、自己写一个jar包五、打包步骤六、方法补充一、安装包pip3 install

linux重启命令有哪些? 7个实用的Linux系统重启命令汇总

《linux重启命令有哪些?7个实用的Linux系统重启命令汇总》Linux系统提供了多种重启命令,常用的包括shutdown-r、reboot、init6等,不同命令适用于不同场景,本文将详细... 在管理和维护 linux 服务器时,完成系统更新、故障排查或日常维护后,重启系统往往是必不可少的步骤。本文

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,