解决方案

系统应用篇(三)--Camera篇

seo靠我 2023-09-23 01:03:03

目录

一、Camera应用的作用和重要性

二、Camera应用的类型和分类

三、Camera应用的架构和组件

四、Camera应用的定制和扩展

五、学习总结 

一、Camera应用的作用和重要性

相机应用的作用和重要SEO靠我性如下表格所示:

作用重要性1. 拍摄照片和录制视频通过Camera应用,用户可以方便地拍摄照片和录制视频,记录重要时刻、美好回忆或者创作内容。相机功能是手机的基本功能之一,对于用户来说具有重要的实用价SEO靠我值和体验价值。2. 视频通话和视频聊天Camera应用也支持视频通话和视频聊天功能,用户可以通过相机进行面对面的远程沟通和交流,提高沟通的效率和质量。尤其在远程工作、远程教育等场景中,视频通话成为必不SEO靠我可少的工具。3. 计算机视觉和图像处理Camera应用为计算机视觉和图像处理提供了源数据,这对于开发人员和研究人员来说非常重要。通过相机获取的图像可以进行图像识别、人脸识别、场景分析等多种计算机视觉任SEO靠我务,为各种应用和研究领域提供数据支持。4. 增强现实和虚拟现实相机应用在增强现实(AR)和虚拟现实(VR)中扮演着重要的角色。通过相机获取实时图像,结合AR和VR技术,可以实现虚拟物体与真实世界的交互SEO靠我、虚拟场景的展示等,为用户带来身临其境的体验。5. 多媒体应用相机应用是多媒体应用的基础组成部分之一,与相册、图库等应用紧密关联。通过相机拍摄的照片和录制的视频可以进行编辑、分享、保存等操作,为用户提SEO靠我供丰富的多媒体体验。

相机应用的作用和重要性,涵盖了拍摄照片和录制视频、视频通话和视频聊天、计算机视觉和图像处理、增强现实和虚拟现实以及多媒体应用等方面。这些功能使得相机应用在用户日常使用和开发领域中具SEO靠我有重要的地位和作用。

二、Camera应用的类型和分类

相机应用的类型和分类如下表格所示:

类型描述1. 原生相机应用原生相机应用是由设备厂商或操作系统提供的默认相机应用程序。它通常具有基本的拍摄和录制功能SEO靠我,并随设备一同提供。原生相机应用通常具有良好的兼容性和稳定性。2. 第三方相机应用第三方相机应用是由独立开发者或公司开发的相机应用程序。它们提供了丰富的功能和定制选项,可以满足不同用户的需求。第三方相SEO靠我机应用通常具有更多的滤镜、特效、手动设置等高级功能。3. 专业相机应用专业相机应用是面向摄影爱好者、专业摄影师或摄影专业人士的应用程序。它们提供了更高级的摄影功能和控制选项,例如手动曝光、白平衡、焦距SEO靠我、快门速度等。专业相机应用通常具有更高的图像质量和更精确的控制能力。4. 社交相机应用社交相机应用专注于用户之间的分享和互动。它们通常具有内置的社交媒体集成,允许用户轻松地拍摄照片或录制视频,并直接分SEO靠我享到社交平台上。社交相机应用也常常提供滤镜、贴纸、标签等社交化的特性。5. AR相机应用AR相机应用结合了增强现实技术和相机功能,可以在相机预览中叠加虚拟物体、场景或效果。它们提供了沉浸式的增强现实体SEO靠我验,允许用户与虚拟内容进行交互、游戏或创作。AR相机应用在娱乐、教育、购物等领域有广泛应用。

相机应用的不同类型和分类,包括原生相机应用、第三方相机应用、专业相机应用、社交相机应用和AR相机应用。每种类SEO靠我型的相机应用都具有不同的特点和定位,满足了不同用户的需求和使用场景。

三、Camera应用的架构和组件

相机应用的架构和组件如下表格所示:

架构和组件描述1. 硬件抽象层(HAL)相机应用与相机硬件之间的接SEO靠我口层。HAL负责处理底层硬件驱动程序与操作系统之间的通信,提供相机功能的抽象接口,以便上层应用程序能够与不同的相机硬件进行交互。2. 相机服务(Camera Service)相机服务是相机应用的核心组SEO靠我件,负责管理相机硬件资源和处理相机功能。它与HAL进行交互,控制相机的打开、关闭、配置和数据传输等操作。相机服务还提供API供上层应用程序调用,实现相机的拍摄、录制、预览等功能。3. 相机框架(CamSEO靠我era Framework)相机框架是相机应用的高级组件,提供了更高级别的功能和控制选项。它包括相机API、相机参数设置、图像处理、拍摄模式、拍摄效果等。相机框架通过与相机服务进行交互,实现相机的各种SEO靠我功能和特性。4. 相机界面(Camera UI)相机界面是用户与相机应用进行交互的界面部分。它包括预览界面、设置界面、拍摄按钮、拍摄模式切换等。相机界面提供了直观的操作界面,让用户可以调整相机参数、预SEO靠我览图像、拍摄照片或录制视频等。5. 图像处理引擎图像处理引擎负责对相机捕获的图像进行处理和优化。它包括图像算法、滤镜、色彩校正、降噪等。图像处理引擎能够提高图像质量、增强细节、改善色彩和对比度等,让拍SEO靠我摄的照片更加出色。

相机应用的架构和组件,包括硬件抽象层(HAL)、相机服务(Camera Service)、相机框架(Camera Framework)、相机界面(Camera UI)和图像处理引擎。SEO靠我这些组件共同协作,实现了相机应用的功能和特性。

四、Camera应用的定制和扩展

1.以高通的骁龙相机中实际需求为例:

解决相机拍照后无法存储在SD卡上的问题强制有拍照倒计时声音解决在相机预览黑屏时按相机键SEO靠我拍照出错的问题增加相机在无照片时缩略图显示图库图标的功能相机 前摄按键操作拍照 默认焦点不在拍照按钮上录像后 切换前后摄按钮焦点异常去掉骁龙相机在获取权限失败后的弹窗

2.解决方案:

1.在SDCard.SEO靠我java文件中的getDirectory()方法中设置sd卡的存储路径:

public String getDirectory() {if (mVolume == null) {return null;SEO靠我}if (mPath == null) {File[] dirs = mContext.getExternalFilesDirs(null);if (dirs != null) {String dirSEO靠我;for (int i=0; i<dirs.length; i++) {if (dirs[i] != null) {dir = dirs[i].getAbsolutePath();if (dir.stSEO靠我artsWith(mVolume.getPath())) {//add begin//mPath = dir;mPath=mVolume.getPath()+/+Environment.DIRECTOSEO靠我RY_DCIM+"/Camera";//add endbreak;}}}}}return mPath;}

2. 在values目录下的bool.xml中将force_count_down_sound设置SEO靠我为true:

<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2011 The Android Open SourceSEO靠我 ProjectLicensed under the Apache License, Version 2.0 (the "License");you may not use this file excSEO靠我ept in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/liceSEO靠我nses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed underSEO靠我 the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, eitherSEO靠我 express or implied.See the License for the specific language governing permissions andlimitations uSEO靠我nder the License. --> <resources><bool name="show_action_bar_title">false</bool><!--SEO靠我 modify begin --><bool name="force_count_down_sound">true</bool><!-- modify end --><bool name="volumSEO靠我e_key_shutter_disable">false</bool> </resources>

3. 在PhotoModule.java中的onKeyDown()方法中的KEYCODESEO靠我_CAMERA选项中,添加onShutterButtonFocus(true),就可解决该bug:

@Overridepublic boolean onKeyDown(int keyCode, KeyESEO靠我vent event) {switch (keyCode) {case KeyEvent.KEYCODE_VOLUME_UP:case KeyEvent.KEYCODE_VOLUME_DOWN:if SEO靠我(CameraUtil.volumeKeyShutterDisable(mActivity)) {return false;}case KeyEvent.KEYCODE_FOCUS:if (/*TODSEO靠我O: mActivity.isInCameraApp() &&*/ mFirstTimeInitialized) {if (event.getRepeatCount() == 0) {onShutteSEO靠我rButtonFocus(true);}return true;}return false;case KeyEvent.KEYCODE_CAMERA:if (mFirstTimeInitializedSEO靠我 && event.getRepeatCount() == 0) {//add beginonShutterButtonFocus(true);//add endonShutterButtonClicSEO靠我k();}return true;case KeyEvent.KEYCODE_DPAD_LEFT:if ( (mCameraState != PREVIEW_STOPPED) && (mFocusMaSEO靠我nager != null) &&(mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING) &&(mFocusManSEO靠我ager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING_SNAP_ON_FINISH) ) {if (mbrightness > MINSEO靠我IMUM_BRIGHTNESS) {mbrightness-=mbrightness_step;synchronized (mCameraDevice) {/* Set the "luma-adaptSEO靠我ation" parameter */mParameters = mCameraDevice.getParameters();mParameters.set("luma-adaptation", StSEO靠我ring.valueOf(mbrightness));mCameraDevice.setParameters(mParameters);}}brightnessProgressBar.setProgrSEO靠我ess(mbrightness);Editor editor = mPreferences.edit();editor.putInt(CameraSettings.KEY_BRIGHTNESS, mbSEO靠我rightness);editor.apply();brightnessProgressBar.setVisibility(View.INVISIBLE);mBrightnessVisible = tSEO靠我rue;}break;case KeyEvent.KEYCODE_DPAD_RIGHT:if ( (mCameraState != PREVIEW_STOPPED) && (mFocusManagerSEO靠我 != null) &&(mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING) &&(mFocusManager.SEO靠我getCurrentFocusState() != mFocusManager.STATE_FOCUSING_SNAP_ON_FINISH) ) {if (mbrightness < MAXIMUM_SEO靠我BRIGHTNESS) {mbrightness+=mbrightness_step;synchronized (mCameraDevice) {/* Set the "luma-adaptationSEO靠我" parameter */mParameters = mCameraDevice.getParameters();mParameters.set("luma-adaptation", String.SEO靠我valueOf(mbrightness));mCameraDevice.setParameters(mParameters);}}brightnessProgressBar.setProgress(mSEO靠我brightness);Editor editor = mPreferences.edit();editor.putInt(CameraSettings.KEY_BRIGHTNESS, mbrightSEO靠我ness);editor.apply();brightnessProgressBar.setVisibility(View.INVISIBLE);mBrightnessVisible = true;}SEO靠我break;case KeyEvent.KEYCODE_DPAD_CENTER:// If we get a dpad center event without any focused view, mSEO靠我ove// the focus to the shutter button and press it.if (mFirstTimeInitialized && event.getRepeatCountSEO靠我() == 0) {// Start auto-focus immediately to reduce shutter lag. After// the shutter button gets theSEO靠我 focus, onShutterButtonFocus()// will be called again but it is fine.onShutterButtonFocus(true);mUI.SEO靠我pressShutterButton();}return true;}return false;}

4. 在CameraActivity.java中onPostExecute()方法添加该功能:

@OveSEO靠我rrideprotected void onPostExecute(Bitmap bitmap) {if (bitmap == null) {//add beginmThumbnail = (ImagSEO靠我eView) findViewById(R.id.preview_thumb);if (mThumbnail != null) {// Clear the image resource when thSEO靠我e bitmap is invalid.try {Drawable appIcon = getPackageManager().getActivityIcon(new ComponentName("cSEO靠我om.google.android.apps.photosgo", "com.google.android.apps.photosgo.home.HomeActivity"));mThumbnail.SEO靠我setImageDrawable(appIcon);mThumbnail.setVisibility(View.VISIBLE);} catch (PackageManager.NameNotFounSEO靠我dException e) {mThumbnail.setImageDrawable(null);mThumbnail.setVisibility(View.GONE);e.printStackTraSEO靠我ce();}//add end}} else {updateThumbnail(bitmap);}mJpegData = null;}

5.在PhotoModule.java的onShutterButtSEO靠我onFocus()中判断并设置快门按钮的焦点:

@Overridepublic void onShutterButtonFocus(boolean pressed) {if (mCameraDeviceSEO靠我 == null|| mPaused || mUI.collapseCameraControls()|| (mCameraState == SNAPSHOT_IN_PROGRESS)|| (mCameSEO靠我raState == PREVIEW_STOPPED)|| (null == mFocusManager)) {Log.v(TAG, "onShutterButtonFocus error case SEO靠我mCameraState = " + mCameraState+ "mCameraDevice = " + mCameraDevice + "mPaused =" + mPaused);return;SEO靠我}synchronized(mCameraDevice) {if (mCameraState == LONGSHOT) {mLongshotActive = false;mCameraDevice.sSEO靠我etLongshot(false);mUI.animateCapture(mLastJpegData);mLastJpegData = null;if (!mFocusManager.isZslEnaSEO靠我bled()) {setupPreview();} else {setCameraState(IDLE);mFocusManager.resetTouchFocus();if (CameraUtil.SEO靠我FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusManager.getFocusMode())) {mCameraDevice.cancelAutoFocus()SEO靠我;}mUI.resumeFaceDetection();}}}// Do not do focus if there is not enough storage.if (pressed && !canSEO靠我TakePicture()) return;if (pressed) {mFocusManager.onShutterDown();} else {// for countdown mode, we SEO靠我need to postpone the shutter release// i.e. lock the focus during countdown.if (!mUI.isCountingDown(SEO靠我)) {mFocusManager.onShutterUp();}}//add beginif(PhotoUI.mThumbnail != null)PhotoUI.mThumbnail.setFocSEO靠我usable(false); if(PhotoUI.mMenuButton != null)PhotoUI.mMenuButton.setFocusable(false); if(PhotoUI.mSSEO靠我witcher != null)PhotoUI.mSwitcher.setFocusable(false); if(PhotoUI.mFrontBackSwitcher != null)PhotoUISEO靠我.mFrontBackSwitcher.setFocusable(false); if(PhotoUI.mShutterButton != null){PhotoUI.mShutterButton.sSEO靠我etFocusedByDefault(true);PhotoUI.mShutterButton.setFocusable(true);PhotoUI.mShutterButton.setFocusabSEO靠我leInTouchMode(true);PhotoUI.mShutterButton.requestFocus();} //add end}

6. 在VideoModule.java中的子线程中设置前后SEO靠我摄按钮的焦点:

Handler mSetViewFocusHandler = new Handler(){public void handleMessage(Message msg) {switch (SEO靠我msg.what){case 1: if(VideoUI.mThumbnail != null)VideoUI.mThumbnail.setFocusable(true); if(VideoUI.mPSEO靠我auseButton != null)VideoUI.mPauseButton.setFocusable(true); if(VideoUI.mMuteButton != null)VideoUI.mSEO靠我MuteButton.setFocusable(true); //add beginif(VideoUI.mFrontBackSwitcher != null)VideoUI.mFrontBackSwSEO靠我itcher.setFocusable(true); //add end //if(VideoUI.mSurfaceView != null)// VideoUI.mSurfaceView.setFoSEO靠我cusable(true); break;case 2:if(VideoUI.mThumbnail != null)VideoUI.mThumbnail.setFocusable(true); if(SEO靠我VideoUI.mPauseButton != null)VideoUI.mPauseButton.setFocusable(true); if(VideoUI.mMuteButton != nullSEO靠我)VideoUI.mMuteButton.setFocusable(true); //add beginif(VideoUI.mFrontBackSwitcher != null)VideoUI.mFSEO靠我rontBackSwitcher.setFocusable(true);//add end // if(VideoUI.mSurfaceView != null)// VideoUI.mSurfaceSEO靠我View.setFocusable(true); if(VideoUI.mMenuButton != null)VideoUI.mMenuButton.setFocusable(true);if(ViSEO靠我deoUI.mSwitcher != null)VideoUI.mSwitcher.setFocusable(true); break; default:break;}};};

7. 在PermissiSEO靠我onsActivity.java中的onRequestPermissionsResult()将获取权限失败后的弹窗给finish()掉:

@Overridepublic void onRequestPeSEO靠我rmissionsResult(int requestCode,String permissions[], int[] grantResults) {if (mShouldRequestCameraPSEO靠我ermission) {if ((grantResults.length >= mIndexPermissionRequestCamera + 1) &&(grantResults[mIndexPerSEO靠我missionRequestCamera] ==PackageManager.PERMISSION_GRANTED)) {mFlagHasCameraPermission = true;} else SEO靠我{mCriticalPermissionDenied = true;}}if (mShouldRequestMicrophonePermission) {if ((grantResults.lengtSEO靠我h >= mIndexPermissionRequestMicrophone + 1) &&(grantResults[mIndexPermissionRequestMicrophone] ==PacSEO靠我kageManager.PERMISSION_GRANTED)) {mFlagHasMicrophonePermission = true;} else {mCriticalPermissionDenSEO靠我ied = true;}}if (mShouldRequestStoragePermission) {if ((grantResults.length >= mIndexPermissionRequeSEO靠我stStorageRead + 1) &&(grantResults[mIndexPermissionRequestStorageWrite] ==PackageManager.PERMISSION_SEO靠我GRANTED) &&(grantResults[mIndexPermissionRequestStorageRead] ==PackageManager.PERMISSION_GRANTED)) {SEO靠我mFlagHasStoragePermission = true;} else {mCriticalPermissionDenied = true;}}if (mShouldRequestLocatiSEO靠我onPermission) {if ((grantResults.length >= mIndexPermissionRequestLocation + 1) &&(grantResults[mIndSEO靠我exPermissionRequestLocation] ==PackageManager.PERMISSION_GRANTED)) {// Do nothing} else {// Do nothiSEO靠我ng}}if (mFlagHasCameraPermission && mFlagHasMicrophonePermission &&mFlagHasStoragePermission) {handlSEO靠我ePermissionsSuccess();} else if (mCriticalPermissionDenied) { // modify begin // hanSEO靠我dlePermissionsFailure();finish();//modify end}}

五、学习总结

参考了Google API中关于Camera的介绍

要访问摄像头,使用相机和自动对焦功能,则清单SEO靠我文件里应包括以下内容:

<uses-permission android:name="android.permission.CAMERA" > <uses-feature androidSEO靠我:name="android.hardware.camera" > <uses-feature android:name="android.hardware.camera.autofoSEO靠我cus" >

1.拍照流程要使用到以下的类并且按步骤进行:

从open(int)获取摄像头的实例;使用getParameters()来获取默认的设置;如果有必要,可调用setParameters(CameSEO靠我ra.Parameters)来修改返回的对象;调用setDisplayOrientation(int)以确保预览的正确方向;【重要事项】:传递完全初始化的SurfaceHolder给setPrevieSEO靠我wDisplay(SurfaceHolder)。如果没有surface, 相机将无法开始预览;【重要事项】:调用startPreview()以开始更新预览图面。必须先开始预览,然后才能拍照;当需要时,SEO靠我可调用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PicturSEO靠我eCallback)用来拍摄照片。等待回调提供实际图像数据;拍照后,预览显示将停止。需要拍摄更多照片时,要再次调用startPreview();调用stopPreview()来停止更新预览图面;【重要SEO靠我事项】:调用 release() 以释放相机以供其他应用程序使用。应用程序应立即在 android.app.Activity.onPause()中释放相机(并在android.app.ActivitySEO靠我.onResume()中re-open())。

2.视频录制模式的相关步骤:

获取并初始化相机并按照拍照流程开始预览取景;调用unlock()去允许媒体进程访问摄像机;将相机传递到 android.medSEO靠我ia.MediaRecorder.setCamera(Camera);录制完成后,调用reconnect()去重新获得并重新锁定相机;如果有需要,重新启动预览并拍摄更多照片或视频;最后一步要像拍照步骤SEO靠我流程一样调用 stopPreview()和release() 来停止预览和释放相机。

本文仅代表个人观点和经验,难免存在不足之处。如果有任何错误或改进的建议,欢迎指正和交流,共同进步。

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2