diff --git a/entry/src/main/ets/constants/CameraConstants.ets b/entry/src/main/ets/constants/CameraConstants.ets index 3b392e8edc5a2fe4e9c84c03c443cb319835ad85..2aa8af96dc96ea2520013464bb03d0671ca1704a 100644 --- a/entry/src/main/ets/constants/CameraConstants.ets +++ b/entry/src/main/ets/constants/CameraConstants.ets @@ -29,19 +29,11 @@ export class CameraConstants { /** * zoom button margin top */ - static readonly PREVIEW_HEIGHT_BUTTON: string = '1400px'; + static readonly PREVIEW_HEIGHT_BUTTON: number = 350; /** * surface height */ - static readonly SURFACE_HEIGHT: string = '1650px'; - /** - * capture - */ - static readonly CAPTURE: string = '拍照'; - /** - * record - */ - static readonly RECORD: string = '录像'; + static readonly SURFACE_HEIGHT: number = 500; /** * Parameter Configuration button size */ diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 9837ec2b93dee956159d98dcbee7627f220e6c38..ff03dcecb660d23efb4f2c7d7721fd9ee029a88e 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -113,21 +113,30 @@ struct XComponentPage { if (this.isFoldAble) { foldAbleStatus = display.getFoldStatus(); this.mXComponentController.setXComponentSurfaceRect({ - surfaceWidth: 1080, - surfaceHeight: 1920 + surfaceWidth: foldAbleStatus === 1 ? 1400 : display.getDefaultDisplaySync().width, + surfaceHeight: this.isFoldAble ? 1400 : 1600 }) display.on('foldStatusChange', (foldStatus: display.FoldStatus) => { - foldAbleStatus = foldStatus // 更新折叠状态控制变量 + if (foldStatus === 3) { + return; + } + foldAbleStatus = foldStatus; if (foldStatus === 1) { cameraPosition = cameraPosition === 0 ? 0 : 2; } else { cameraPosition = cameraPosition === 0 ? 0 : 1; } - cameraShooting(isVideo, cameraPosition, surfaceId, context, foldAbleStatus); + setTimeout(() => { + this.mXComponentController.setXComponentSurfaceRect({ + surfaceWidth: foldAbleStatus === 1 ? 1400 : display.getDefaultDisplaySync().width, + surfaceHeight: this.isFoldAble ? 1400 : 1600 + }) + cameraShooting(isVideo, cameraPosition, surfaceId, context, foldAbleStatus); + }, 500) }) } zoomRatioRange = await cameraShooting(isVideo, cameraPosition, surfaceId, context, foldAbleStatus); - }, 500); + }, 200); }); } @@ -155,7 +164,7 @@ struct XComponentPage { .visibility(this.isPhoto || this.isFront ? Visibility.Hidden : Visibility.Visible) .onClick(() => { this.isStabilization = !this.isStabilization; - videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context); + videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context, foldAbleStatus); isVideo = true; }); Image(this.isMovingPhoto ? $r('app.media.live_photo_on') : $r('app.media.live_photo_off')) @@ -172,28 +181,28 @@ struct XComponentPage { .visibility(this.isFront ? Visibility.Hidden : Visibility.Visible) .bindMenu(this.isPhoto ? [ { - value: '关闭', + value: 'off', action: (): void => { this.flashPic = $r('app.media.ic_camera_public_flash_off'); this.switchFlash(camera.FlashMode.FLASH_MODE_CLOSE); } }, { - value: '打开', + value: 'on', action: (): void => { this.flashPic = $r('app.media.ic_camera_public_flash_on'); this.switchFlash(camera.FlashMode.FLASH_MODE_OPEN); } }, { - value: '自动', + value: 'auto', action: (): void => { this.flashPic = $r('app.media.ic_camera_public_flash_auto'); this.switchFlash(camera.FlashMode.FLASH_MODE_AUTO); } }, { - value: '常亮', + value: 'always_on', action: (): void => { this.flashPic = $r('app.media.ic_camera_public_flash_always_on'); this.switchFlash(camera.FlashMode.FLASH_MODE_ALWAYS_OPEN); @@ -202,14 +211,14 @@ struct XComponentPage { ] : [ { - value: '关闭', + value: 'off', action: (): void => { this.flashPic = $r('app.media.ic_camera_public_flash_off'); this.switchFlash(camera.FlashMode.FLASH_MODE_CLOSE); } }, { - value: '常亮', + value: 'on', action: (): void => { this.flashPic = $r('app.media.ic_camera_public_flash_always_on'); this.switchFlash(camera.FlashMode.FLASH_MODE_ALWAYS_OPEN); @@ -228,7 +237,8 @@ struct XComponentPage { action: (): void => { qualityLevel = 0; stopRecordPreview(); - videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context); + videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context, + foldAbleStatus); } }, { @@ -236,7 +246,8 @@ struct XComponentPage { action: (): void => { qualityLevel = 1; stopRecordPreview(); - videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context); + videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context, + foldAbleStatus); } } ] @@ -277,13 +288,13 @@ struct XComponentPage { } else { currentFov = getVideoZoom(); } - this.isShowZoom = false; + this.isShowZoom = false }) ) .onLoad(async () => { this.mXComponentController.setXComponentSurfaceRect({ - surfaceWidth: previewSize.height, - surfaceHeight: previewSize.width + surfaceWidth: foldAbleStatus === 1 ? 1400 : display.getDefaultDisplaySync().width, + surfaceHeight: this.isFoldAble ? 1400 : 1600 }); surfaceId = this.mXComponentController.getXComponentSurfaceId(); }) @@ -335,16 +346,16 @@ struct XComponentPage { }) } .visibility(this.isFront || this.isStabilization ? Visibility.Hidden : Visibility.Visible) - .margin({ top: CameraConstants.PREVIEW_HEIGHT_BUTTON }) + .margin({ top: this.isFoldAble ? CameraConstants.PREVIEW_HEIGHT_BUTTON : 400 }) - Text(this.zoom === zoomRatioRange[0] ? '广角' : this.zoom.toFixed(1) + 'x') + Text(this.zoom === zoomRatioRange[0] ? 'wide angle' : this.zoom.toFixed(1) + 'x') .fontColor(Color.White) - .margin({ top: '1000px' }) + .margin({ top: 250 }) .visibility(this.isShowZoom && !this.isFront ? Visibility.Visible : Visibility.Hidden) } Row() { - Text(CameraConstants.CAPTURE) + Text($r("app.string.Photo")) .fontColor(this.isPhoto ? Color.White : Color.Gray) .onClick(async () => { if (!this.isPhoto) { @@ -352,30 +363,18 @@ struct XComponentPage { isVideo = false; stopRecordPreview(); this.Initialize(); - this.mXComponentController.setXComponentSurfaceRect(foldAbleStatus === 0 ? { - surfaceWidth: CameraConstants.PREVIEW_HEIGHT, - surfaceHeight: CameraConstants.PREVIEW_WIDTH - } : { - surfaceWidth: 1080, - surfaceHeight: 1920 - } - ); cameraShooting(isVideo, cameraPosition, surfaceId, context, foldAbleStatus); } }) - Text(CameraConstants.RECORD) + Text($r("app.string.Video")) .fontColor(this.isPhoto ? Color.Gray : Color.White) .onClick(() => { if (this.isPhoto) { this.isPhoto = false; releaseCamera(); // 1080P - this.mXComponentController.setXComponentSurfaceRect({ - surfaceWidth: 1080, - surfaceHeight: 1920 - }); this.Initialize(); - videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context); + videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context, foldAbleStatus); isVideo = true; } }) @@ -410,7 +409,7 @@ struct XComponentPage { .height(CameraConstants.CAPTURE_SIZE) .visibility(this.isPhoto ? Visibility.Visible : Visibility.Hidden) .onClick(() => { - capture(); + capture(this.isFront); this.currentPic = true; }) Image($r('app.media.record')) @@ -433,7 +432,7 @@ struct XComponentPage { this.flashPic = $r('app.media.ic_camera_public_flash_off'); videoUri = await stopRecord(); stopRecordPreview(); - videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context); + videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context, foldAbleStatus); setTimeout(() => { this.getThumbnail(); }, 500); @@ -459,7 +458,7 @@ struct XComponentPage { cameraShooting(isVideo, cameraPosition, surfaceId, context, foldAbleStatus); } else { stopRecordPreview(); - videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context); + videoRecording(this.isStabilization, cameraPosition, qualityLevel, surfaceId, context, foldAbleStatus); } this.Initialize(); this.isFront = cameraPosition != 0; diff --git a/entry/src/main/ets/utils/CameraShooter.ets b/entry/src/main/ets/utils/CameraShooter.ets index 6333c40580609c88b7a2d9230d99a2e894f7c6ce..b407de8545eac13b9627836b38e6a1f97cd5413d 100644 --- a/entry/src/main/ets/utils/CameraShooter.ets +++ b/entry/src/main/ets/utils/CameraShooter.ets @@ -17,21 +17,20 @@ import { camera } from '@kit.CameraKit'; import { videoRecording } from './VideoRecorder'; import { BusinessError } from '@kit.BasicServicesKit'; import { photoAccessHelper } from '@kit.MediaLibraryKit'; -import { CameraConstants } from '../constants/CameraConstants'; import { common } from '@kit.AbilityKit'; +import { display } from '@kit.ArkUI'; let previewOutput: camera.PreviewOutput; let cameraInput: camera.CameraInput; let photoSession: camera.PhotoSession; let photoOutPut: camera.PhotoOutput; -let previewSize: camera.Size; let currentContext: Context; let uri: string; export async function cameraShooting(isVideo: boolean, cameraPosition: number, surfaceId: string, context: Context, foldAbleStatus: number): Promise { if (isVideo) { - return videoRecording(false, cameraPosition, 0, surfaceId, context); + return videoRecording(false, cameraPosition, 0, surfaceId, context, foldAbleStatus); } currentContext = context; isVideo = false; @@ -61,43 +60,26 @@ export async function cameraShooting(isVideo: boolean, cameraPosition: number, s let previewProfilesArray: camera.Profile[] = cameraOutputCap.previewProfiles; let photoProfilesArray: camera.Profile[] = cameraOutputCap.photoProfiles; - let photoSize: camera.Size = cameraPosition === 0 ? { - width: CameraConstants.FRONT_WIDTH, - height: CameraConstants.FRONT_HEIGHT - } : - foldAbleStatus === 0 ? - { - width: CameraConstants.PHOTO_WIDTH, - height: CameraConstants.PHOTO_HEIGHT - } : { - width: 3840, - height: 2160 - }; - previewSize = cameraPosition === 0 ? { - width: CameraConstants.PREVIEW_WIDTH, - height: CameraConstants.PREVIEW_HEIGHT - } : foldAbleStatus === 0 ? { - width: CameraConstants.PHOTO_WIDTH, - height: CameraConstants.PHOTO_HEIGHT - } : { - width: 1920, - height: 1080 - } - ; - let photoProfile: undefined | camera.Profile = photoProfilesArray.find((profile: camera.Profile) => { - return profile.size.width === photoSize.width && profile.size.height === photoSize.height; - }); let previewProfile: undefined | camera.Profile = previewProfilesArray.find((profile: camera.Profile) => { - return profile.size.width === previewSize.width && profile.size.height === previewSize.height; + let screen = display.getDefaultDisplaySync(); + if (screen.width <= 1080) { + return profile.size.height === 1080 && profile.size.width === 1440; + } else if (screen.width <= 1440 && screen.width > 1080) { + return profile.size.height === 1440 && profile.size.width === 1920; + } + return profile.size.height <= screen.width && profile.size.height >= 1080 && + (profile.size.width / profile.size.height) < (screen.height / screen.width) + && (profile.size.width / profile.size.height) > + (foldAbleStatus === display.FoldStatus.FOLD_STATUS_EXPANDED ? 1 : 4 / 3); + }); + let photoProfile: undefined | camera.Profile = photoProfilesArray.find((profile: camera.Profile) => { + if (previewProfile) { + return profile.size.width <= 4096 && profile.size.width >= 2448 + && profile.size.height === (foldAbleStatus === display.FoldStatus.FOLD_STATUS_EXPANDED ? 1 : + (previewProfile.size.height / previewProfile.size.width)) * profile.size.width; + } + return undefined; }); - if (cameraPosition === 0 && foldAbleStatus != 0) { - photoProfile = photoProfilesArray.find((profile: camera.Profile) => { - return profile.size.width === 1920 && profile.size.height === 1080; - }); - previewProfile = previewProfilesArray.find((profile: camera.Profile) => { - return profile.size.width === 1920 && profile.size.height === 1080; - }); - } previewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId); if (previewOutput === undefined) { return []; @@ -151,10 +133,11 @@ export function setPhotoSmoothZoom(zoom: number): void { photoSession.setSmoothZoom(zoom); } -export function capture(): void { +export function capture(isFront: boolean): void { let settings: camera.PhotoCaptureSetting = { quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, rotation: camera.ImageRotation.ROTATION_0, + mirror: isFront }; photoOutPut.capture(settings); } diff --git a/entry/src/main/ets/utils/VideoRecorder.ets b/entry/src/main/ets/utils/VideoRecorder.ets index 4179215ee1ed0cc66d70804aa96eea898c7a10f2..4313f8035d9a05ac9a913f58a635f63c09829fec 100644 --- a/entry/src/main/ets/utils/VideoRecorder.ets +++ b/entry/src/main/ets/utils/VideoRecorder.ets @@ -18,6 +18,7 @@ import { media } from '@kit.MediaKit'; import { photoAccessHelper } from '@kit.MediaLibraryKit'; import { fileIo } from '@kit.CoreFileKit'; import { common } from '@kit.AbilityKit'; +import { display } from '@kit.ArkUI'; let file: fileIo.File; let previewOutput: camera.PreviewOutput; @@ -28,7 +29,7 @@ let videoSession: camera.VideoSession; let uri: string; export async function videoRecording(isStabilization: boolean, cameraPosition: number, qualityLevel: number, - surfaceId: string, context: Context): Promise { + surfaceId: string, context: Context, foldAbleStatus: number): Promise { let cameraManager: camera.CameraManager = camera.getCameraManager(context); if (!cameraManager) { return []; @@ -59,26 +60,38 @@ export async function videoRecording(isStabilization: boolean, cameraPosition: n if (!videoProfilesArray) { return []; } - let videoSize: camera.Size; - if (qualityLevel === 1 && cameraPosition === 0) { - // 4K - videoSize = { - width: 3840, - height: 2160 - }; - } else { - // 1080P - videoSize = { - width: 1920, - height: 1080 + let previewProfile: undefined | camera.Profile = previewProfilesArray.reverse().find((profile: camera.Profile) => { + let screen = display.getDefaultDisplaySync(); + if (screen.width <= 1080) { + return profile.size.height === 1080 && profile.size.width === 1440; + } else if (screen.width <= 1440 && screen.width > 1080) { + return profile.size.height === 1440 && profile.size.width === 1920; } - } - let videoProfile: undefined | camera.VideoProfile = videoProfilesArray.find((profile: camera.VideoProfile) => { - return profile.size.width === videoSize.width && profile.size.height === videoSize.height && - profile.frameRateRange.max === (cameraPosition === 0 ? 60 : 30); + return profile.size.height <= screen.width && profile.size.height >= 1080 && + (profile.size.width / profile.size.height) < (screen.height / screen.width) + && (profile.size.width / profile.size.height) > + (foldAbleStatus === display.FoldStatus.FOLD_STATUS_EXPANDED ? 1 : 4 / 3); }) - let previewProfile: undefined | camera.Profile = previewProfilesArray.find((profile: camera.Profile) => { - return profile.size.width === 1920 && profile.size.height === 1080; + let videoProfile: undefined | camera.VideoProfile = videoProfilesArray.find((profile: camera.VideoProfile) => { + if (previewProfile && cameraPosition === 1) { + return profile.size.width >= 1080 && profile.size.height >= 1080 + && profile.size.height === (foldAbleStatus === display.FoldStatus.FOLD_STATUS_EXPANDED ? 1 : + (previewProfile.size.height / previewProfile.size.width)) * profile.size.width + && profile.frameRateRange.max === 30; + } + if (previewProfile && qualityLevel === 0) { + return profile.size.width <= 1920 && profile.size.width >= 1080 && profile.size.height >= 1080 + && profile.size.height === (foldAbleStatus === display.FoldStatus.FOLD_STATUS_EXPANDED ? 1 : + (previewProfile.size.height / previewProfile.size.width)) * profile.size.width + && profile.frameRateRange.max === 60; + } + if (previewProfile && qualityLevel === 1 && cameraPosition === 0) { + return profile.size.width <= 4096 && profile.size.width >= 3000 + && profile.size.height === (foldAbleStatus === display.FoldStatus.FOLD_STATUS_EXPANDED ? 1 : + (previewProfile.size.height / previewProfile.size.width)) * profile.size.width + && profile.frameRateRange.max === 60; + } + return undefined; }) // Set the parameters based on the actual hardware range. let aVRecorderProfile: media.AVRecorderProfile = { @@ -90,9 +103,9 @@ export async function videoRecording(isStabilization: boolean, cameraPosition: n videoBitrate: 32000000, videoCodec: qualityLevel === 1 && cameraPosition === 0 ? media.CodecMimeType.VIDEO_HEVC : media.CodecMimeType.VIDEO_AVC, - videoFrameWidth: videoSize.width, - videoFrameHeight: videoSize.height, - videoFrameRate: cameraPosition === 0 ? 60 : 30 + videoFrameWidth: videoProfile?.size.width, + videoFrameHeight: videoProfile?.size.height, + videoFrameRate: cameraPosition === 0 ? 60 : 30, } let options: photoAccessHelper.CreateOptions = { title: Date.now().toString() @@ -140,11 +153,14 @@ export async function videoRecording(isStabilization: boolean, cameraPosition: n videoSession.addOutput(previewOutput); videoSession.addOutput(videoOutput); await videoSession.commitConfig(); - if(videoSession.isVideoStabilizationModeSupported(camera.VideoStabilizationMode.MIDDLE)){ + if (videoSession.isVideoStabilizationModeSupported(camera.VideoStabilizationMode.MIDDLE)) { videoSession.setVideoStabilizationMode(isStabilization ? camera.VideoStabilizationMode.AUTO : camera.VideoStabilizationMode.OFF); } await videoSession.start(); + setTimeout(() => { + videoSession.setZoomRatio(0.95); + }, 700); // Obtains the variable focal length ratio range supported by the camera. let zoomRatioRange = videoSession.getZoomRatioRange(); return zoomRatioRange; diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index 526624cd09c4fe4963b526e0254840ad17e57e5e..b12dbd6e89f815c3f9fcb734295a2ac0a683b047 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -11,6 +11,14 @@ { "name": "EntryAbility_label", "value": "三方相机" + }, + { + "name": "Photo", + "value": "拍照" + }, + { + "name": "Video", + "value": "录像" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/en_US/element/string.json b/entry/src/main/resources/en_US/element/string.json index 1ad23aed6adf7c1dc76a75517939d2b130584abc..ad90c55ca2e37008b2237731c3f87cafce4dfc00 100644 --- a/entry/src/main/resources/en_US/element/string.json +++ b/entry/src/main/resources/en_US/element/string.json @@ -6,11 +6,19 @@ }, { "name": "EntryAbility_desc", - "value": "权限请求" + "value": "Permission Request" }, { "name": "EntryAbility_label", "value": "Camera" + }, + { + "name": "Photo", + "value": "Photo" + }, + { + "name": "Video", + "value": "Video" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index 65e7f4f4c4d3bc4e1670553b1140184fd915d64f..d290e53d9f616ca79cb59c446ae7bb40259477c3 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -11,6 +11,14 @@ { "name": "EntryAbility_label", "value": "三方相机" + }, + { + "name": "Photo", + "value": "拍照" + }, + { + "name": "Video", + "value": "录像" } ] } \ No newline at end of file