123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822 |
- import image from '@ohos.multimedia.image';
- import fs from "@ohos.file.fs"
- import CommonEventManager from '@ohos.commonEventManager'
- import uploadInstance from '../../common/util/UploadUtil';
- import router from '@ohos.router';
- import { DrawingInfo, DrawingPage } from '../../viewmodel/DrawingInfo';
- import CommonConstants from '../../common/constants/CommonConstants';
- import ProcessRequest from '../../common/util/request/ProcessRequest';
- import RequestParamModel from '../../viewmodel/RequestParamModel';
- import { ConfirmDialogParams } from '../../viewmodel/ConfirmDialogParam';
- import { ConfirmDialog } from '../ConfirmDialog';
- import promptAction from '@ohos.promptAction';
- const TAG = "Process camera upload"
- @Component
- export struct MultiMediaCollect {
- private scrollerPhoto: Scroller = new Scroller()
- //
- @State isExpanded: boolean = false
- //闪光模式 0:自动 1:开启 2:关闭
- @State selectedFlashMode:number = 0
- //选择的照片索引
- @State selectedPhotoIndex:number = -1
- //拍照按键缩放
- @State shootButtonClick:number =1
- // 旋转角度
- @State rotateAngle: number = 0
- // 照片缩放比例
- @State scaleValue: number = 1
- // 照片X轴偏移
- @State offsetX: number = 0
- // 照片Y轴偏移
- @State offsetY: number = 0
- // 照片上次缩放值
- @State lastScale: number = 1
- // 照片上次X偏移
- @State lastOffsetX: number = 0
- // 照片上次Y偏移
- @State lastOffsetY: number = 0
- // 正在上传
- @State isUploading: boolean = false
- // 照片列表
- @State photoList:DrawingInfo[]=[]
- // 获取本地live照片
- @State commodityPixelMap: PixelMap | null = null;
- // 拍照动作是否完成
- @State isCapturing: boolean = false;
- // 是否停止预览
- @State isStopView: boolean = false;
- // 控制帧率
- @State readTimer:number = 0
- // 预览操作
- private previewManager: PreviewManager | null = null;
- //创建订阅者
- subscriber: CommonEventManager.CommonEventSubscriber | null = null;
- //订阅相机回调
- subscribeInfo: CommonEventManager.CommonEventSubscribeInfo = { events: ["sonycamera_callback"] };
- //提示确认弹窗
- commonDialogController: CustomDialogController | null = null;
- private showConfirmDialog(params: ConfirmDialogParams) {
- if (this.commonDialogController) {
- this.commonDialogController.close()
- }
- this.commonDialogController = new CustomDialogController({
- builder: ConfirmDialog({
- title: params.title || '提示',
- message: params.message,
- onConfirm: params.onConfirm
- }),
- cancel: () => console.log('用户取消操作'),
- customStyle: true,
- autoCancel:false,
- maskColor: 'rgba(0,0,0,0.6)'
- });
- this.commonDialogController.open();
- }
- //订阅回调(code=3代表连接成功,code=2代表拍照成功)
- createSubscriber = async () => {
- this.subscriber = await CommonEventManager.createSubscriber(this.subscribeInfo);
- if (this.subscriber) {
- console.info(TAG, "创建订阅回调成功");
- CommonEventManager.subscribe(this.subscriber, (err, data) => {
- if (err?.code) {
- console.error(TAG, "SubscribeCallBack err=" + JSON.stringify(err));
- return;
- }
- console.info(TAG, "SubscribeCallBack data=" + JSON.stringify(data));
- if (data?.code !== undefined) {
- switch (data.code) {
- case 2:
- this.uploadPhoto(); // 拍照成功
- break;
- case 3:
- console.info(TAG, "开始预览");
- this.startView(); // 连接成功
- break;
- case -1:
- console.info(TAG,'连接故障')
- break;
- case 5:
- console.info(TAG,'暂停预览')
- break;
- }
- }
- //0001:自动闪光 0002:关闭闪光 0003:开启闪光
- if (data?.parameters?.flash_mode) {
- const flashMode:string = data.parameters.flash_mode
- console.info(TAG, `收到闪光模式: ${flashMode}`);
- switch (flashMode) {
- case '0001':
- this.selectedFlashMode = 0
- break;
- case '0002':
- this.selectedFlashMode = 2
- break;
- case '0003':
- this.selectedFlashMode = 1
- break;
- default:
- console.warn(TAG, `未知闪光模式: ${flashMode}`);
- }
- }
- });
- }
- };
- //加载照片
- loadPhotos=async()=>{
- let res = await ProcessRequest.post('/api/v1/process/media/page', {
- } as RequestParamModel) as DrawingPage;
- this.photoList=res.records??[]
- }
- //删除照片
- deletePhoto=async(photoId:string)=>{
- let res = await ProcessRequest.post('/api/v1/process/media/del', {
- id: photoId
- } as RequestParamModel) as DrawingPage;
- this.loadPhotos()
- }
- //旋转照片
- private rotateImage(angle: number) {
- this.offsetX = 0;
- this.offsetY = 0;
- this.rotateAngle += angle
- if (this.rotateAngle >= 360) {
- this.rotateAngle -= 360
- } else if (this.rotateAngle < 0) {
- this.rotateAngle += 360
- }
- if(this.rotateAngle==90||this.rotateAngle==270)
- {
- this.scaleValue=0.63
- }else {
- this.scaleValue=1
- }
- }
- // 重置图片变换
- private resetImageTransform() {
- this.rotateAngle = 0
- this.scaleValue = 1
- this.offsetX = 0
- this.offsetY = 0
- this.lastScale = 1
- this.lastOffsetX = 0
- this.lastOffsetY = 0
- }
- //连接相机
- connectCamera = async () => {
- CommonEventManager.publish("opensession", (err) => {
- if (err?.code) {
- console.info(TAG,"Publish openSession err=" + JSON.stringify(err))
- } else {
- console.info(TAG,"Publish openSession succeed ")
- }
- })
- }
- //查询闪光模式
- queryFlashMode = async () => {
- CommonEventManager.publish("queryflashmode", (err) => {
- if (err?.code) {
- console.info(TAG,"Publish openSession err=" + JSON.stringify(err))
- } else {
- console.info(TAG,"Publish openSession succeed ")
- }
- })
- }
- //开始预览
- startView=()=>{
- CommonEventManager.publish("startview", (err) => {
- if (err?.code) {
- console.error(TAG, JSON.stringify(err));
- } else {
- this.isCapturing = false;
- this.isStopView =false;
- this.liveShow();
- }
- });
- }
- //停止预览
- stopView=async()=>{
- CommonEventManager.publish("stopview", (err) => {
- if (err?.code) {
- console.error(TAG, JSON.stringify(err));
- } else {
- this.isCapturing = false;
- this.isStopView =true;
- }
- });
- }
- //重连相机
- reconnectCamera=async()=>{
- this.showConfirmDialog({
- title: '重连USB',
- message: `请重连USB后点击确定!`,
- onConfirm: async()=> {
- await new Promise<void>((resolve, reject) => {
- CommonEventManager.publish("stopview", (err) => {
- if (err) return reject(err);
- CommonEventManager.publish("closesession", (err) => {
- err ? reject(err) : resolve();
- });
- });
- });
- await new Promise<void>((resolve, reject) => {
- CommonEventManager.publish("reconnect", (err) => {
- if (err) return reject(err);
- resolve();
- });
- });
- promptAction.showToast({
- message: '相机正在重连中...',
- duration: 3000,
- bottom: 500
- });
- await sleep(3000);
- await this.connectCamera()
- //await this.liveShow()
- }
- });
- }
- //开始预览 50ms一张图片(20帧)
- liveShow = async () => {
- this.previewManager = new PreviewManager(getContext(this));
- let index = 0;
- this.readTimer = setInterval(async () => {
- if (!this.isStopView && !this.isCapturing) {
- try {
- const success = await this.previewManager!.processFrame(index);
- if (success) {
- this.commodityPixelMap = this.previewManager!.getActiveBuffer();
- }
- } catch (error) {
- console.warn(TAG, "预览更新失败:", error);
- }
- }
- }, 50);
- };
- //断开相机(停止预览->关闭连接)
- disconnectCamera = () => {
- CommonEventManager.publish("stopview", (err) => {
- if (err?.code) {
- console.info(TAG,"Publish stopview err=" + JSON.stringify(err))
- } else {
- console.info(TAG,"Publish stopview succeed ")
- CommonEventManager.publish("closesession", (err) => {
- if (err?.code) {
- console.info(TAG,"Publish closesession err=" + JSON.stringify(err))
- } else {
- console.info(TAG,"Publish closesession succeed ")
- }
- })
- }
- })
- }
- //拍照(停止预览->拍照->开始预览)
- takePhoto = async () => {
- this.isStopView = true;
- this.isCapturing = true;
- CommonEventManager.publish("stopview", (err) => {
- if (err?.code) {
- console.info(TAG,"Publish stopview err=" + JSON.stringify(err));
- this.isCapturing = false;
- } else {
- console.info(TAG,"Publish Publish stopview succeed");
- CommonEventManager.publish("shootonly", (err) => {
- if (err?.code) {
- console.info(TAG,"Publish shootonly error=" + JSON.stringify(err));
- this.isCapturing = false;
- } else {
- console.info(TAG,"Publish Publish shootonly succeed");
- }
- });
- }
- });
- };
- //设置闪光模式
- setFlashMode = (mode: 'openflash' | 'closeflash' | 'autoflash') => {
- this.isStopView = true;
- CommonEventManager.publish("stopview", (err) => {
- if (err?.code) {
- console.info(TAG,"Publish stopview err=" + JSON.stringify(err));
- } else {
- console.info(TAG,"Publish Publish stopview succeed");
- CommonEventManager.publish(mode, (err) => {
- if (err?.code) {
- console.info(TAG,"Publish shootonly error=" + JSON.stringify(err));
- } else {
- console.info(TAG,"Publish Publish shootonly succeed");
- CommonEventManager.publish("startview", (err) => {
- this.isStopView = false;
- if (err?.code) {
- console.info(TAG,"Publish shootonly error=" + JSON.stringify(err));
- }else{
- console.info(TAG,"Publish Publish shootonly succeed");
- }
- })
- }
- });
- }
- });
- }
- //上传照片
- uploadPhoto=()=>{
- let imageUri: string = "/data/storage/el2/base/haps/entry/files/image_base64.txt"
- try {
- uploadInstance.startUploadBase64(imageUri, () => {
- this.loadPhotos()
- this.isUploading = false
- this.startView();//上传完恢复预览
- })
- } catch (error) {
- console.error(TAG,"upload failed:", error.code);
- }
- }
- async aboutToAppear() {
- this.loadPhotos();
- await this.createSubscriber();
- await this.connectCamera();
- await this.queryFlashMode();
- }
- aboutToDisappear(): void {
- this.isStopView = true;
- sleep(100)
- this.disconnectCamera()
- if (this.subscriber) {
- CommonEventManager.unsubscribe(this.subscriber);
- }
- if (this.readTimer) {
- clearInterval(this.readTimer);
- }
- if (this.commodityPixelMap) {
- this.commodityPixelMap.release();
- this.commodityPixelMap = null;
- }
- if (this.previewManager) {
- this.previewManager.release();
- }
- }
- build() {
- Row() {
- Stack(){
- if (this.commodityPixelMap) {
- if (this.selectedPhotoIndex === -1) {
- Image(this.commodityPixelMap)
- .width('100%')
- .height('100%')
- .objectFit(ImageFit.Fill)
- }
- }
- if(this.isUploading){
- Column() {
- Text('正在上传中...')
- .fontSize($r('app.float.fontSize_30'))
- .margin({bottom:'10%'})
- LoadingProgress()
- .color(Color.Blue)
- .width('25%')
- .width('25%')
- }
- .height('30%')
- .width('25%')
- .backgroundColor(Color.White)
- .borderRadius($r('app.float.virtualSize_16'))
- .justifyContent(FlexAlign.Center)
- }
- if(this.selectedPhotoIndex === -1){
- Row() {
- Image(
- this.selectedFlashMode === 0 ? $r('app.media.process_flash_auto') :
- this.selectedFlashMode === 1 ? $r('app.media.process_flash_open') :
- $r('app.media.process_flash_close')
- )
- .width($r('app.float.virtualSize_48'))
- .height($r('app.float.virtualSize_48'))
- .enabled(!this.isUploading)
- .onClick(() => {
- this.isExpanded = !this.isExpanded
- })
- .margin({right:'5%'})
- if (this.isExpanded) {
- Row() {
- Row(){
- Text('自动')
- .fontSize($r('app.float.fontSize_24'))
- .fontColor(this.selectedFlashMode===0?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
- }
- .width('33.3%')
- .height('100%')
- .justifyContent(FlexAlign.Center)
- .borderRadius($r('app.float.virtualSize_16'))
- .backgroundColor(this.selectedFlashMode===0?$r('app.color.0A84FF'):$r('app.color.60000000'))
- .onClick(() => {
- this.setFlashMode('autoflash')
- this.isExpanded = false
- this.selectedFlashMode = 0
- })
- Row(){
- Text('开启')
- .fontSize($r('app.float.fontSize_24'))
- .fontColor(this.selectedFlashMode===1?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
- }
- .width('33.3%')
- .height('100%')
- .justifyContent(FlexAlign.Center)
- .borderRadius($r('app.float.virtualSize_16'))
- .backgroundColor(this.selectedFlashMode===1?$r('app.color.0A84FF'):$r('app.color.60000000'))
- .onClick(() => {
- this.setFlashMode('openflash')
- this.isExpanded = false
- this.selectedFlashMode = 1
- })
- Row(){
- Text('关闭')
- .fontSize($r('app.float.fontSize_24'))
- .fontColor(this.selectedFlashMode===2?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
- }
- .width('33.3%')
- .height('100%')
- .justifyContent(FlexAlign.Center)
- .borderRadius($r('app.float.virtualSize_16'))
- .backgroundColor(this.selectedFlashMode===2?$r('app.color.0A84FF'):$r('app.color.60000000'))
- .onClick(() => {
- this.setFlashMode('closeflash')
- this.isExpanded = false
- this.selectedFlashMode = 2
- })
- }
- .animation({ duration: 300, curve: Curve.EaseOut }) // 展开动画
- .backgroundColor($r('app.color.60000000'))
- .borderRadius($r('app.float.virtualSize_16'))
- .width('85%')
- .height('100%')
- }
- }
- .justifyContent(FlexAlign.Start)
- .alignItems(VerticalAlign.Bottom)
- .position({ x: '2%', y: '92%' })
- .height('5%')
- .width('24%')
- Image(this.shootButtonClick===1?$r('app.media.process_no_shoot'):$r('app.media.process_shoot'))
- .width($r('app.float.virtualSize_88'))
- .height($r('app.float.virtualSize_88'))
- .scale({ x: this.shootButtonClick, y: this.shootButtonClick })
- .borderRadius($r('app.float.fontSize_16'))
- .enabled(!this.isUploading)
- .animation({
- duration: 200,
- curve: Curve.Linear
- })
- .onClick(() => {
- this.shootButtonClick = 0.9;
- setTimeout(() => {
- this.shootButtonClick = 1;
- }, 200);
- if(this.isUploading){
- return
- }
- this.isUploading = true
- this.takePhoto();
- })
- .position({ x: '48%', y: '90%' })
- Row(){
- Text("重连相机")
- .fontColor($r('app.color.FFFFFF'))
- .fontSize($r('app.float.fontSize_24'))
- }
- .width('10%')
- .height('6%')
- .backgroundColor($r('app.color.20FFFFFF'))
- .position({ x: '88%', y: '91%' })
- .borderRadius($r('app.float.virtualSize_16'))
- .justifyContent(FlexAlign.Center)
- .onClick(()=>{
- this.reconnectCamera()
- })
- }
- else{
- Stack() {
- Image(CommonConstants.PICTURE_URL_PREFIX + this.photoList[this.selectedPhotoIndex].filePath)
- .width('100%')
- .height('100%')
- .objectFit(ImageFit.Fill)
- .rotate({ angle: this.rotateAngle })
- .scale({ x: this.scaleValue, y: this.scaleValue })
- .borderRadius($r('app.float.virtualSize_16'))
- .translate({ x: this.offsetX, y: this.offsetY })
- .gesture(
- GestureGroup(GestureMode.Exclusive,
- // 双指缩放手势
- PinchGesture()
- .onActionStart(() => {
- this.lastScale = this.scaleValue
- this.lastOffsetX = this.offsetX
- this.lastOffsetY = this.offsetY
- })
- .onActionUpdate((event: GestureEvent) => {
- this.scaleValue = this.lastScale * event.scale
- })
- .onActionEnd(() => {
- //缩放最小比例为1
- if (this.scaleValue < 1) {
- //旋转90°或者270°的最小缩小比例为0.63
- if(this.rotateAngle==90||this.rotateAngle==270) {
- if(this.scaleValue<0.63){
- this.scaleValue = 0.63
- }
- } else {
- this.scaleValue = 1
- }
- }
- //缩放最大比例为4
- if (this.scaleValue > 4) this.scaleValue = 4
- }),
- // 单指滑动手势
- PanGesture()
- .onActionStart(() => {
- if (this.scaleValue <= 1) return;
- this.lastOffsetX = this.offsetX;
- this.lastOffsetY = this.offsetY;
- })
- .onActionUpdate((event: GestureEvent) => {
- if (this.scaleValue <= 1) return;
- let dx = event.offsetX;
- let dy = event.offsetY;
- const sensitivity = 0.5 * this.scaleValue;
- // 临时计算新位置
- let newOffsetX = this.lastOffsetX;
- let newOffsetY = this.lastOffsetY;
- switch(this.rotateAngle % 360) {
- case 0:
- newOffsetX += dx * sensitivity;
- newOffsetY += dy * sensitivity;
- break;
- case 90:
- newOffsetX -= dy * sensitivity;
- newOffsetY += dx * sensitivity;
- break;
- case 180:
- newOffsetX -= dx * sensitivity;
- newOffsetY -= dy * sensitivity;
- break;
- case 270:
- newOffsetX += dy * sensitivity;
- newOffsetY -= dx * sensitivity;
- break;
- }
- this.offsetX = newOffsetX;
- this.offsetY = newOffsetY;
- })
- .onActionEnd(() => {
- if (this.scaleValue <= 1) {
- // 如果缩放比例<=1,直接重置位置
- this.offsetX = 0;
- this.offsetY = 0;
- return;
- }
- // 计算最大允许偏移量(基于缩放比例)
- const maxOffsetX = (this.scaleValue - 1) * 500; //500是容器的半宽
- const maxOffsetY = (this.scaleValue - 1) * 345; //345是容器的半高
- // 检查X轴边界
- if (Math.abs(this.offsetX) > maxOffsetX) {
- this.offsetX = this.offsetX > 0 ? maxOffsetX : -maxOffsetX;
- }
- // 检查Y轴边界
- if (Math.abs(this.offsetY) > maxOffsetY) {
- this.offsetY = this.offsetY > 0 ? maxOffsetY : -maxOffsetY;
- }
- // 添加回弹动画
- animateTo({
- duration: 300,
- curve: Curve.EaseOut
- }, () => {
- this.offsetX = this.offsetX;
- this.offsetY = this.offsetY;
- });
- })
- )
- )
- }
- .width('100%')
- .height('100%')
- .borderRadius($r('app.float.virtualSize_16'))
- .clip(true)
- Row()
- {
- Row(){
- Image($r('app.media.process_back_camera'))
- .width($r('app.float.virtualSize_80'))
- .height($r('app.float.virtualSize_80'))
- .onClick(()=>{
- this.selectedPhotoIndex=-1
- this.startView()
- })
- }
- .width('10%')
- .justifyContent(FlexAlign.Start)
- Row({space:20}){
- Image($r("app.media.process_photo_reset"))
- .width($r('app.float.virtualSize_80'))
- .height($r('app.float.virtualSize_80'))
- .onClick(()=>{
- this.resetImageTransform()
- })
- Image($r('app.media.process_photo_turn_left'))
- .width($r('app.float.virtualSize_80'))
- .height($r('app.float.virtualSize_80'))
- .onClick(()=>{
- this.rotateImage(-90)
- })
- Image($r('app.media.process_photo_turn_right'))
- .width($r('app.float.virtualSize_80'))
- .height($r('app.float.virtualSize_80'))
- .onClick(()=>{
- this.rotateImage(90)
- })
- Image($r('app.media.process_photo_delete'))
- .width($r('app.float.virtualSize_80'))
- .height($r('app.float.virtualSize_80'))
- .onClick(()=>{
- this.showConfirmDialog({
- title: '删除照片',
- message: `确定要删除照片吗?`,
- onConfirm: ()=> {
- const photosNum = this.photoList.length
- const photoId=this.photoList[this.selectedPhotoIndex].id
- //如果是图册最后一张照片,显示前一张照片,没有照片则返回拍照页面
- if(this.selectedPhotoIndex===photosNum-1)
- {
- this.selectedPhotoIndex--
- }
- this.deletePhoto(photoId)
- }
- });
- })
- }.width('88%')
- .justifyContent(FlexAlign.End)
- .margin({right :'2%'})
- }.width('98%')
- .height('10%')
- .position({x:'2%',y:'90%'})
- }
- }
- .width('86%')
- .height('100%')
- .backgroundColor($r('app.color.000000'))
- .border({width:2})
- Column(){
- List({ space: 8,scroller:this.scrollerPhoto }) {
- ForEach(this.photoList, (item: DrawingInfo, index) => {
- ListItem() {
- Column({space:4}){
- Column(){
- Image(CommonConstants.PICTURE_URL_PREFIX+item.filePath)
- .objectFit(ImageFit.Fill)
- .borderRadius($r('app.float.virtualSize_16'))
- .height('97%')
- .width('98%')
- .opacity(index === this.selectedPhotoIndex ? 0.8 : 1) // 20% 透明度
- }
- .backgroundColor(index === this.selectedPhotoIndex ? $r('app.color.30D158') : '')
- .width('90%')
- .justifyContent(FlexAlign.Center)
- .alignItems(HorizontalAlign.Center)
- .borderRadius($r('app.float.virtualSize_16'))
- .height('85%')
- Text(`${item.updated}`)
- .fontSize($r('app.float.fontSize_12'))
- .fontColor($r('app.color.FFFFFF'))
- .width('90%')
- .textAlign(TextAlign.Start)
- }
- .width('100%')
- .height('100%')
- .justifyContent(FlexAlign.Start)
- .alignItems(HorizontalAlign.Center)
- .enabled(!this.isUploading)
- .onClick(()=>{
- this.selectedPhotoIndex = index;
- this.resetImageTransform()
- this.stopView();
- })
- }.height('19%')
- .margin({bottom:'2%'})
- })
- }
- .width('100%')
- .margin({top:'2%',bottom:'2%'})
- .height('96%')
- }
- .width('14%')
- .height('100%')
- }
- .width('100%')
- .height('100%')
- //.backgroundColor($r('app.color.10FFFFFF'))
- .borderRadius($r('app.float.virtualSize_16'))
- }
- }
- function sleep(ms: number): Promise<void> {
- return new Promise((resolve) => setTimeout(resolve, ms));
- }
- class PreviewManager {
- private context: Context;
- private activeBuffer: PixelMap | null = null;
- private nextBuffer: PixelMap | null = null;
- private isProcessing: boolean = false;
- private lastFrameTime: number = 0;
- private frameInterval: number = 50;
- constructor(context: Context) {
- this.context = context;
- }
- async processFrame(index: number): Promise<boolean> {
- if (this.isProcessing) return false;
- const now = Date.now();
- if (now - this.lastFrameTime < this.frameInterval) {
- return false;
- }
- this.isProcessing = true;
- try {
- const filePath = `${this.context.filesDir}/live${index}.jpg`;
- try {
- fs.accessSync(filePath);
- } catch {
- this.isProcessing = false;
- return false;
- }
- const imageSource = image.createImageSource(filePath);
- if (!imageSource) {
- this.isProcessing = false;
- return false;
- }
- this.nextBuffer = await imageSource.createPixelMap();
- imageSource.release();
- if (this.activeBuffer) {
- this.activeBuffer.release();
- }
- this.activeBuffer = this.nextBuffer;
- this.nextBuffer = null;
- this.lastFrameTime = now;
- return true;
- } catch (error) {
- console.warn(TAG, "处理预览帧失败:", error);
- return false;
- } finally {
- this.isProcessing = false;
- }
- }
- getActiveBuffer(): PixelMap | null {
- return this.activeBuffer;
- }
- release() {
- if (this.activeBuffer) {
- this.activeBuffer.release();
- this.activeBuffer = null;
- }
- if (this.nextBuffer) {
- this.nextBuffer.release();
- this.nextBuffer = null;
- }
- }
- }
- interface CameraParam {
- flash_mode: string;
- moduleName?: string;
- }
|