HarmonyOS NEXT智能终端应用开发 课件 第9章 多媒体开发_第1页
HarmonyOS NEXT智能终端应用开发 课件 第9章 多媒体开发_第2页
HarmonyOS NEXT智能终端应用开发 课件 第9章 多媒体开发_第3页
HarmonyOS NEXT智能终端应用开发 课件 第9章 多媒体开发_第4页
HarmonyOS NEXT智能终端应用开发 课件 第9章 多媒体开发_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第9章多媒体开发鸿蒙平台提供了丰富的多媒体业务开发支持,支持开发者在系统上快速开发主流的媒体业务,满足各种常规或者高频使用场景。鸿蒙平台提供的媒体开发支持包括音频服务、视频服务、相机服务、图片处理服务、铃声服务、扫码服务等各种基础开发支持包。本章对常用的媒体服务的实用进行介绍。目录9.1播放音频视频9.2使用cameraPicker拍摄照片和视频9.3图片处理9.4信息分享9.5案例:图片处理展示和分享9.6练习:自制在线音乐播放器9.1播放音频视频最为常用的音频服务包括播放音频和录制音频。鸿蒙为此应用需求提供了AVPlayer和类AVRecorder类,本节对使用这两个类播放和录制音频进行介绍。9.1.1使用AVPlayer播放音频使用AVPlayer可以实现端到端地播放原始媒体资源,播放包括本地音频资源或者网络音频资源在内的资源。音频播放是基于状态机控制的:在任何时候播放器总是处于一个特定的状态,在特定的状态,只能调用指定的方法。简单来说,AVPlayer对象的状态及其在各个状态可以调用的方法如下:新创建的播放器处于“idle”状态,此时可以设置音频源;设置了音频源的播放器则处于“initialized”状态,此时可以调用prepare()方法对音频解码;解码完成后则处于“prepared”状态,此时可以调用player()方法播放音频,并使播放器处于“playing”状态;在“playing”状态,可以调用pause()暂停,使播放器处于“paused”状态,或者调用stop()方法使播放器处于“stopped”状态,或者播放完毕则处于“completed”状态。下面举例说明如何使用AVPlayer播放音频。这个例子播放资源目录下的指定音频文件,在界面显示两个按钮和一个进度条,两个按钮用于控制播放和停止播放,进度条用于显示播放进度。为此,新建名称为ch0901的鸿蒙工程,在resources/rawfile目录下放置一个名称为music.wav的音频文件,然后修改Index.ets为如下内容:import{media}from'@kit.MediaKit';

@Entry@ComponentstructIndex{@Statecurrent:number=0;@Statetotal:number=100;privateplayer:media.AVPlayer|null=null;asyncplayAudio(){if(this.player){this.player.release();}this.player=awaitmedia.createAVPlayer();

this.player.on('stateChange',(state)=>{if(state==='initialized'){this.player?.prepare();}elseif(state==='prepared'){this.player?.play();}});this.player.on('durationUpdate',(t)=>{this.total=t;});this.player.on('timeUpdate',(c)=>{this.current=c;});this.player.on('error',(err)=>{this.getUIContext().getPromptAction().showToast({'message':'发生了错误:'+JSON.stringify(err)});this.player?.reset();});

constcontext=getContext();constfileDescriptor=awaitcontext.resourceManager.getRawFd('music.wav');this.player.fdSrc=fileDescriptor;}

stopAudio(){if(this.player?.state=='playing'){this.player.stop();this.player.release();}}

build(){Column(){Progress({value:this.current,total:this.total,type:ProgressType.Linear}).height(60).width('100%').margin(10)Button("播放").height(40).width('100%').margin(10).onClick(()=>{this.playAudio();})Button("停止").height(40).width('100%').margin(10).onClick(()=>{this.stopAudio();})}.height('100%').width('100%')}}9.1.2使用Video组件播放视频使用Video播放视频是最简单最快捷的播放视频的方法。第6章已经介绍了如何使用Video组件播放视频,并通过具体例子介绍了Video组件的使用。如果不需要对视频的播放过程进行更为细粒度的控制,建议使用Video组件完成视频播放功能。如果在应用场景中需要对视频的播放过程进行细粒度的控制,则可以使用AVPlayer播放视频。但是,使用AVPlayer播放视频比播放音频要难一些,因为,需要为视频播放创建播放窗口。下面一节介绍如何使用AVPlayer播放视频。9.1.3使用AVPlayer播放视频AVPlayer不仅可以播放音频,也可以用来播放视频。与使用AVPlayer播放音频类似,使用AVPlayer播放视频也是基于状态机进行的,并且状态的状态及在各个状态可以执行的方法也是类似的。与使用AVPlayer播放音频不同,使用AVPlayer播放视频需要一个与之关联的窗口显示视频内容。常用的用于显示视频的组件是XComponent,它是一个用于渲染媒体的组件。在创建XComponent组件时,需要指定一个类型为XComponentController的控制,用于对XCompnent的窗口事件进行管理。下面举一个例子说明如何使用AVPlayer播放视频。这个例子播放一个指定的视频,在通过点击视频窗口可以暂停或者继续播放,同时,在视频的下方还显示了视频以毫秒为单位的播放进度和总时长。为此,新建名称为ch0902的工程,修改Index.ets为如下内容:import{media}from'@kit.MediaKit';import{BusinessError}from'@kit.BasicServicesKit';importdisplayfrom'@ohos.display';

@Entry@ComponentV2structAVPlayerTest{privatexcController:XComponentController=newXComponentController();privatesurfaceID:string='';privatevideoPlayer:media.AVPlayer|null=null;

@Localw:number=100;//视频的宽度和高度@Localh:number=100;@LocalisPlaying:boolean=true;@Localcurrent:number=0;//视频当前时间@Localduration:number=0;//视频总时长

//创建AVPlayerasyncinitAVPlayer(){media.createAVPlayer().then(async(video:media.AVPlayer)=>{if(video===undefined){return;}this.videoPlayer=video;this.setAVPlayerCallback(this.videoPlayer);

constcontext=getContext();constfileDescriptor=awaitcontext.resourceManager.getRawFd('example.mp4');this.videoPlayer.fdSrc=fileDescriptor;//this.avPlayer.url='http://某个视频的URL/...';})}

//avPlayer回调函数setAVPlayerCallback(avPlayer:media.AVPlayer){avPlayer.on('videoSizeChange',(width:number,height:number)=>{letdw=display.getDefaultDisplaySync().width;letdh=display.getDefaultDisplaySync().height;this.w=px2vp(dw);this.h=px2vp((dw/width)*height);});

avPlayer.on('seekDone',(seekDoneTime)=>{(`seektimeis${seekDoneTime}`);});avPlayer.on('speedDone',(speed)=>{(`speedis${speed}`);});

//监听当前播放进度,单位为毫秒(ms)avPlayer.on('timeUpdate',(time:number)=>{this.current=time;})

//监听错误事件,该事件仅用于错误提示,不需要用户停止播控动作avPlayer.on('error',(err:BusinessError)=>{(`errormessageis${err.message}.state:${avPlayer.state}`);avPlayer.reset();})

//状态机切换事件回调类型avPlayer.on('stateChange',async(state:string)=>{switch(state){case'idle'://成功调用reset接口后触发该状态机上报(`stateidle.`);break;case'initialized'://avplayer设置播放源后触发该状态上报(`stateinitialized.`);avPlayer.surfaceId=this.surfaceID;//设置显示视频的XCompnent的IDavPlayer.prepare();break;case'prepared'://prepare调用成功后上报该状态机(`stateprepared.`);this.duration=avPlayer.duration;this.current=avPlayer.currentTime;avPlayer.play();break;case'playing'://play成功调用后触发该状态机上报(`stateplaying.`);this.isPlaying=true;break;case'paused':(`statepaused.`);this.isPlaying=false;break;case'stopped':(`statestopped.`);this.isPlaying=false;break;case'completed'://播放结束后触发该状态机上报(`statecompleted.`);this.isPlaying=false;break;case'released':(`statereleased.`);break;case'error':console.error(`stateerror.`);this.isPlaying=false;avPlayer.reset();break;default:(`stateunknown.`);break;}})}

build(){Column(){XComponent({id:'xComponent',type:XComponentType.SURFACE,controller:this.xcController}).onLoad(()=>{this.surfaceID=this.xcController.getXComponentSurfaceId();this.initAVPlayer()}).width(this.w).height(this.h)Progress({value:this.current,total:this.duration,type:ProgressType.Linear}).height(10).width('100%')Text(this.current+'/'+this.duration).width('100%').height(30).fontColor(Color.White).textAlign(TextAlign.Center)}.backgroundColor(Color.Black).height('100%').width('100%').onClick(()=>{if(this.isPlaying){this.videoPlayer!.pause();}else{if(this.videoPlayer!.state==='prepared'||this.videoPlayer!.state==='paused'||this.videoPlayer!.state==='completed'){this.videoPlayer!.play();}}})}

aboutToDisappear(){if(this.videoPlayer==null){(`avPlayerhasnotinitaboutToDisappear`);return;}this.videoPlayer.release((err)=>{if(err==null){(`videoReleasereleasesuccess`);}else{console.error(`videoReleasereleasefailed:${JSON.stringify(err.message)}`);}});}

onPageHide(){if(this.videoPlayer){try{this.videoPlayer.pause();(`avPause==`);}catch(e){console.error(`avPause==${JSON.stringify(e)}`);}}this.isPlaying=false;}}9.2使用cameraPicker拍摄照片和视频基于鸿蒙平台提供的CameraKit(相机服务)可以开发各种类型的相机应用,甚至可以对相机的各个参数进行深度控制,如控制闪光灯和曝光时间、对焦或调焦等。除非需要开发一个自己的相机程序,一般情况下,使用系统提供的cameraPicker模块可以完成拍摄照片和拍摄视频的需求。本节对cameraPicker的使用进行介绍。使用cameraPicker是最简单有效的拍摄照片和视频的方式,并且,由于照片的拍摄和确认都是由用户进行主动确认,因此应用开发者可以不用申请操作相机的相关权限。下面举一个例子说明如何使用cameraPicker拍摄照片和视频。这个例子使用cameraPicker打开系统的相机程序拍摄照片或者视频,拍摄完成后将在程序的Image组件或者Video组件显示拍摄的照片或者播放视频。为此,新建名称ch0903的工程,修改Index.ets文件为如下代码:import{camera,cameraPickeraspicker}from'@kit.CameraKit';import{fileIo,fileUri}from'@kit.CoreFileKit';

@Entry@ComponentstructIndex{@StateimgSrc:string='';@StatevideoSrc:string='';

privatecreatePickerProfile(context:Context):picker.PickerProfile{letpathDir=context.filesDir;letfileName=`${newDate().getTime()}`;letfilePath=pathDir+`/${fileName}.tmp`;fileIo.createRandomAccessFileSync(filePath,fileIo.OpenMode.CREATE);

leturi=fileUri.getUriFromPath(filePath);letpickerProfile:picker.PickerProfile={cameraPosition:camera.CameraPosition.CAMERA_POSITION_BACK,saveUri:uri};returnpickerProfile;}

privateasyncgetPickerResult(context:Context,pickerProfile:picker.PickerProfile):Promise<picker.PickerResult>{letresult:picker.PickerResult=awaitpicker.pick(context,[picker.PickerMediaType.PHOTO,picker.PickerMediaType.VIDEO],pickerProfile);(`pickerresultCode:${result.resultCode},resultUri:${result.resultUri},mediaType:${result.mediaType}`);returnresult;}

privategetContext():Context|undefined{letuiContext:UIContext=this.getUIContext();letcontext:Context|undefined=uiContext.getHostContext();returncontext;}

build(){RelativeContainer(){Column(){Image(this.imgSrc).width('100%').height(250).backgroundColor(Color.Black).margin(5);Video({src:this.videoSrc}).width('100%').height(250).autoPlay(true);Button("TestPickerPhoto&Video").fontSize(20).fontWeight(FontWeight.Bold).onClick(async()=>{letcontext=this.getContext();if(context===undefined){return;}letpickerProfile=this.createPickerProfile(context);letresult=awaitthis.getPickerResult(context,pickerProfile);if(result.resultCode==0){if(result.mediaType===picker.PickerMediaType.PHOTO){this.imgSrc=result.resultUri;}else{this.videoSrc=result.resultUri;}}}).margin(5);

}.alignRules({center:{anchor:'__container__',align:VerticalAlign.Center},middle:{anchor:'__container__',align:HorizontalAlign.Center}});}.height('100%').width('100%')}}9.3图片处理开发者可以使用鸿蒙系统的ImageKit,也就是图片处理服务,对图片/图像进行操作,包括对图片进行缩放、旋转、透明度、移位、翻转等操作。在可以对图片进行操作之前,需要对图片进行解码。例如,对一张保存在某个文件中的PNG格式的图片,需要从文件中读取图片字节流,进行解码并生成PixelMap,也称为称为位图的图片数据结构。一旦得到了PixelMap图片结构,就可以对图片进行各种处理。处理完成后,可以将处理结果按照指定的图片压缩格式,例如JPG或者PNG等格式保存到指定的文件中。对图片的处理过程如图。可以使用image模块的createImageSource()方法夺取图片文件并得到一个ImageSource对象,通过ImageSource对象解码得到图片的位图对象PixelMap,通过PixelMap可以对图片及逆行各种操作,包括:旋转、缩放、透明度变换等操作。最后,可以通过ImagePacker将PixelMap对象再次压缩,并可以将压缩结果写入到图片文件中。下面举例说明如何对图片进行操作。首先新建名称为ch0904的工程,在工程的资源目录的rawfile目录下放置一张要操作的图片。这个例子允许用户对图片进行如下操作:获取图片基本信息、垂直翻转图片、剪裁图片到指定大小、将图片旋转90度,还可以将处理后的图片保存到程序私有目录的文件中。为此,修改Intex.ets为如下代码:import{image}from'@kit.ImageKit'import{BusinessError}from'@kit.BasicServicesKit';import{fileIo}from'@kit.CoreFileKit';import{common}from'@kit.AbilityKit';

@Entry@ComponentstructTest{@Stateimagepath:ResourceStr=$rawfile('a02.jpg');@Stateimagepixel:image.PixelMap|undefined=undefined;privateimageSource:image.ImageSource|undefined=undefined;

privateasyncinit(){constcontext=getContext();constfileDescriptor=awaitcontext.resourceManager.getRawFd('a02.jpg');this.imageSource=image.createImageSource(fileDescriptor);}

onDidBuild():void{this.init();}

build(){Column(){Image(this.imagepath).width('100%').height(250).margin(5)Button('获取图片信息').width('100%').height(36).margin(5).onClick(async()=>{letpx=awaitthis.imageSource?.createPixelMap({});px?.getImageInfo().then((info:image.ImageInfo)=>{this.getUIContext().getPromptAction().showToast({'message':info.size.width+':'+info.size.height});}).catch((err:BusinessError)=>{this.getUIContext().getPromptAction().showToast({'message':JSON.stringify(err)});});})Button('垂直翻转').width('100%').height(36).margin(5).onClick(async()=>{letpx=awaitthis.imageSource?.createPixelMap({});px?.flip(false,true);this.imagepixel=px;})Button('剪裁到指定大小').width('100%').height(36).margin(5).onClick(async()=>{letpx=awaitthis.imageSource?.createPixelMap({});px?.crop({x:0,y:0,size:{height:1000,width:600}});this.imagepixel=px;})Button('旋转90度').margin(5).width('100%').height(36).onClick(async()=>{letpx=awaitthis.imageSource?.createPixelMap({});px?.rotate(90);this.imagepixel=px;})Button('保存结果图像到程序目录').margin(5).width('100%').height(36).onClick(()=>{letcontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;constimagePackerApi=image.createImagePacker();letpackOpts:image.PackingOption={format:"image/jpeg",quality:100};constpath:string=context.filesDir+"/"+newDate().getTime()+".jpg";letfile=fileIo.openSync(path,fileIo.OpenMode.CREATE|fileIo.OpenMode.READ_WRITE);imagePackerApi.packToFile(this.imagepixel,file.fd,packOpts).then(()=>{this.getUIContext().getPromptAction().showToast({'message':'写入文件成功:'+path});}).catch((error:BusinessError)=>{console.error('Failedtopacktheimage.Andtheerroris:'+error);}).finally(()=>{fileIo.closeSync(file.fd);})})Image(this.imagepixel).margin(5).width('100%').height(250).margin(5)}.width('100%').height('100%').justifyContent(FlexAlign.Start)}}在处理图片后,可以通过点击保存结果图像到程序目录按钮将处理的结果图片保存到程序目录。此时,可以打开程序目录,发现在程序目录下由多个处理后的图片文件,如图。9.4信息分享应用程序可以使用鸿蒙系统提供的ShareKit实现信息分享功能。常用的可用于分享的信息包括文字、图片、视频。这三类信息的分享方式和过程是类似的。下面对分享图片、视频、文本进行介绍。9.4.1分享图片第一步:导入相关功能模块import{systemShare}from'@kit.ShareKit';import{uniformTypeDescriptorasutd}from'@kit.ArkData';import{common}from'@kit.AbilityKit';import{fileUri}from'@kit.CoreFileKit';import{BusinessError}from'@kit.BasicServicesKit';第二步:构造要分享的图片数据letuiContext:UIContext=this.getUIContext();letcontext:Context=uiContext.getHostContext()asContext;letfilePath=context.filesDir+'/exampleImage.jpg';//要分享的图片//获取精准的utd类型。这里分享一张JPG格式的图片letutdTypeId=utd.getUniformDataTypeByFilenameExtension('.jpg',utd.UniformDataType.IMAGE);letshareData:systemShare.SharedData=newsystemShare.SharedData({utd:utdTypeId,uri:fileUri.getUriFromPath(filePath),title:'图片标题',//不传title字段时,显示图片文件名description:'图片描述',//不传description字段时,显示图片大小//thumbnail:newUint8Array()//缩略图预览,不传则默认使用原图预览});第三步:启动分享面板进行信息分享//进行分享面板显示letcontroller:systemShare.ShareController=newsystemShare.ShareController(shareData);letuiContext:UIContext=this.getUIContext();letcontext=uiContext.getHostContext()ascommon.UIAbilityContext;controller.show(context,{selectionMode:systemShare.SelectionMode.SINGLE,previewMode:systemShare.SharePreviewMode.DETAIL,}).then(()=>{('ShareControllershowsuccess.');}).catch((error:BusinessError)=>{console.error(`ShareControllererror.code:${error.code},message:${error.message}`);});9.4.2分享视频第一步:导入相关模块import{systemShare}from'@kit.ShareKit';import{uniformTypeDescriptorasutd}from'@kit.ArkData';import{common}from'@kit.AbilityKit';import{fileUri}from'@kit.CoreFileKit';import{image}from'@kit.ImageKit';import{BusinessError}from'@kit.BasicServicesKit';第二步:生成视频封面图//生成视频封面图letuiContext:UIContext=this.getUIContext();letcontext:Context=uiContext.getHostContext()asContext;letthumbnailPath=context.filesDir+'/exampleImage.jpg';//视频封面图片letimageSource:image.ImageSource=image.createImageSource(thumbnailPath);letimagePacker:image.ImagePacker=image.createImagePacker();letbuffer:ArrayBuffer=awaitimagePacker.packToData(imageSource,{format:'image/jpeg',//建议适当压缩,图片过大无法拉起分享.quality:30});第三步:构造要分享的视频数据//构造ShareData,需配置一条有效数据信息letfilePath=contextFaker.filesDir+'/exampleVideo.mp4';//要分享的视频letutdTypeId=utd.getUniformDataTypeByFilenameExtension('.mp4',utd.UniformDataType.VIDEO);letshareData:systemShare.SharedData=newsystemShare.SharedData({utd:utdTypeId,uri:fileUri.getUriFromPath(filePath),title:'视频标题',//视频标题description:'视频描述',//视频描述thumbnail:newUint8Array(buffer),//视频封面预览图,不传则使用视频第一帧预览图});第四步:启动分享面板分享视频//进行分享面板显示letcontroller:systemShare.ShareController=newsystemShare.ShareController(shareData);letcontext:common.UIAbilityContext=uiContext.getHostContext()ascommon.UIAbilityContext;controller.show(context,{selectionMode:systemShare.SelectionMode.SINGLE,previewMode:systemShare.SharePreviewMode.DETAIL,}).then(()=>{('ShareControllershowsuccess.');}).catch((error:BusinessError)=>{console.error(`ShareControllererror.code:${error.code},message:${error.message}`);});9.4.3分享文本信息第一步:导入相关模块import{systemShare}from'@kit.ShareKit';import{uniformTypeDescriptorasutd}from'@kit.ArkData';import{common}from'@kit.AbilityKit';import{BusinessError}from'@kit.BasicServicesKit';第二步:构造要分享的文本数据//构造ShareData,需配置一条有效数据信息letshareData:systemShare.SharedData=newsystemShare.SharedData({utd:utd.UniformDataType.TEXT,content:'这是一段文本内容',//要分享的文本内容title:'文本内容',//标题description:'文本描述',//thumbnail:newUint8Array()//传入的缩略图,不传则显示默认文本图标});第三步:启动分享面板//进行分享面板显示letcontroller:systemShare.ShareController=newsystemShare.ShareController(shareData);letuiContext:UIContext=this.getUIContext();letcontext:common.UIAbilityContext=uiContext.getHostContext()ascommon.UIAbilityContext;controller.show(context,{selectionMode:systemShare.SelectionMode.SINGLE,previewMode:systemShare.SharePreviewMode.DETAIL,}).then(()=>{('ShareControllershowsuccess.');}).catch((error:BusinessError)=>{console.error(`ShareControllererror.code:${error.code},message:${error.message}`);});9.5案例:图片处理展示和分享完善9.3节图片处理的例子,在这里,将扩展这个例子,采用网格形式显示已经处理并保存的图片缩略图,长按图片可以将图片分享给任何需要的程序。9.5.1案例目标在9.3节的图片处理例子中,程序可以对选定的图片进行处理,包括:旋转、缩放、翻转等,闭关可以根据用户需要将处理的结果图片保存到程序的私有目录下。在这一节的将进一步扩展这个程序,使程序具备如下功能:(1)对选定图片进行处理,并将处理的结果直接保存到应用程序的私有目录下;(2)以垂直布局方式显示图片,同时,长按图片可以分享图片到其他应用。9.5.2案例分析根据程序的功能需求,这个程序至少包括两个页面:其一,图片处理页面,这也是程序的主页面;其二,以垂直布局形式显示图片并分享图片页面。根据前面的章节介绍可知,既可以使用多Ability方式,也可以使用单Ability多页面的方式实现多界面应用程序。对于这个案例,使用单Ability多页面的方式实现多界面及其界面之前的导航。为此,程序将包括如下页面文件:(1)Index.ets,入口页面,在其中可以对图片进行处理并保存,同时也包含进入图片预览页面;(2)Preview.ets,图片显示页面,长按图片,可以分享图片到其他应用。9.5.3案例实施首先新建名称为ch0905的工程,在质检员目录resources目录下的rawfile目录下放置一张待处理的图片,然后修改Index.ets为如下代码:import{image}from'@kit.ImageKit'import{BusinessError}from'@kit.BasicServicesKit';import{fileIo}from'@kit.CoreFileKit';import{Router}from'@kit.ArkUI';

@Entry@ComponentstructIndex{@Stateipath:ResourceStr=$rawfile('a01.jpg');@Stateipm:image.PixelMap|undefined=undefined;@Stateena:boolean=true;privateisource:image.ImageSource|undefined=undefined;

onDidBuild():void{this.init();}

privateasyncinit(){letcontext=getContext();letfileDescriptor=awaitcontext.resourceManager.getRawFd('a01.jpg');this.isource=image.createImageSource(fileDescriptor);}

privatesave(pixel:PixelMap|undefined){if(!pixel){this.ena=true;return;}

letcontext=getContext();constipaker=image.createImagePacker();letoptions:image.PackingOption={format:"image/jpeg",quality:50};constpath:string=context.filesDir+"/"+newDate().getTime()+".jpg";letfile=fileIo.openSync(path,fileIo.OpenMode.CREATE|fileIo.OpenMode.READ_WRITE);ipaker.packToFile(pixel,file.fd,options).then(()=>{this.getUIContext().getPromptAction().showToast({'message':'写入文件成功:'+path});}).catch((error:BusinessError)=>{console.error('Failedtopacktheimage.Andtheerroris:'+error);}).finally(()=>{fileIo.closeSync(file.fd);this.ena=true;})}

build(){Column(){Image(this.ipath).width('100%').height(240).margin(5)Button('随机翻转并保存').width('100%').height(36).margin(5).enabled(this.ena).onClick(async()=>{letpx=this.isource?.createPixelMapSync({});letrint=Math.floor(Math.random()*10);letv:boolean=rint>=5?true:false;px?.flipSync(!v,v);this.ipm=px;this.ena=false;setTimeout(()=>{this.save(px);},1000);})Button('随机剪裁并保存').width('100%').height(36).margin(5).enabled(this.ena).onClick(async()=>{letpx=this.isource?.createPixelMapSync({});letw=Math.floor(Math.random()*1600);leth=Math.floor(Math.random()*1000);px?.cropSync({x:0,y:0,size:{height:h,width:w}});this.ipm=px;this.ena=false;setTimeout(()=>{this.save(px);},1000);})Button('随机旋转并保存').width('100%').height(36).margin(5).enabled(this.ena).onClick(async()=>{letpx=this.isource?.createPixelMapSync({});letangle=Math.floor(Math.random()*360);px?.rotateSync(angle);this.ipm=px;this.ena=false;setTimeout(()=>{this.save(px);},1000);})Button('随机透明度并保存').width('100%').height(36).margin(5).enabled(this.ena).onClick(async()=>{letpx=this.isource?.createPixelMapSync({});letopacity=Math.random();px?.opacitySync(opacity);this.ipm=px;this.ena=false;setTimeout(()=>{this.save(px);},1000);})Button('查看处理结果图片').width('100%').height(36).margin(5).enabled(this.ena).onClick(async()=>{letr:Router=this.getUIContext().getRouter();r.pushUrl({url:'pages/Preview',//目标url},(err)=>{if(err){return;}})})Image(this.ipm).margin(5).width('100%').height(240).margin(5)}.width('100%').height('100%').justifyContent(FlexAlign.Start)}}然后新建页面Preview.ets,并修改文件为如下代码:import{fileIo}from'@kit.CoreFileKit';import{image}from'@kit.ImageKit';import{systemShare}from'@kit.ShareKi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论