【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

相关文章

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

Linux系统之dns域名解析全过程

《Linux系统之dns域名解析全过程》:本文主要介绍Linux系统之dns域名解析全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、dns域名解析介绍1、DNS核心概念1.1 区域 zone1.2 记录 record二、DNS服务的配置1、正向解析的配置

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重