目录
一、Camera应用的作用和重要性
二、Camera应用的类型和分类
三、Camera应用的架构和组件
四、Camera应用的定制和扩展
五、学习总结
相机应用的作用和重要性如下表格所示:
作用 | 重要性 |
---|---|
1. 拍摄照片和录制视频 | 通过Camera应用,用户可以方便地拍摄照片和录制视频,记录重要时刻、美好回忆或者创作内容。相机功能是手机的基本功能之一,对于用户来说具有重要的实用价值和体验价值。 |
2. 视频通话和视频聊天 | Camera应用也支持视频通话和视频聊天功能,用户可以通过相机进行面对面的远程沟通和交流,提高沟通的效率和质量。尤其在远程工作、远程教育等场景中,视频通话成为必不可少的工具。 |
3. 计算机视觉和图像处理 | Camera应用为计算机视觉和图像处理提供了源数据,这对于开发人员和研究人员来说非常重要。通过相机获取的图像可以进行图像识别、人脸识别、场景分析等多种计算机视觉任务,为各种应用和研究领域提供数据支持。 |
4. 增强现实和虚拟现实 | 相机应用在增强现实(AR)和虚拟现实(VR)中扮演着重要的角色。通过相机获取实时图像,结合AR和VR技术,可以实现虚拟物体与真实世界的交互、虚拟场景的展示等,为用户带来身临其境的体验。 |
5. 多媒体应用 | 相机应用是多媒体应用的基础组成部分之一,与相册、图库等应用紧密关联。通过相机拍摄的照片和录制的视频可以进行编辑、分享、保存等操作,为用户提供丰富的多媒体体验。 |
相机应用的作用和重要性,涵盖了拍摄照片和录制视频、视频通话和视频聊天、计算机视觉和图像处理、增强现实和虚拟现实以及多媒体应用等方面。这些功能使得相机应用在用户日常使用和开发领域中具有重要的地位和作用。
相机应用的类型和分类如下表格所示:
类型 | 描述 |
---|---|
1. 原生相机应用 | 原生相机应用是由设备厂商或操作系统提供的默认相机应用程序。它通常具有基本的拍摄和录制功能,并随设备一同提供。原生相机应用通常具有良好的兼容性和稳定性。 |
2. 第三方相机应用 | 第三方相机应用是由独立开发者或公司开发的相机应用程序。它们提供了丰富的功能和定制选项,可以满足不同用户的需求。第三方相机应用通常具有更多的滤镜、特效、手动设置等高级功能。 |
3. 专业相机应用 | 专业相机应用是面向摄影爱好者、专业摄影师或摄影专业人士的应用程序。它们提供了更高级的摄影功能和控制选项,例如手动曝光、白平衡、焦距、快门速度等。专业相机应用通常具有更高的图像质量和更精确的控制能力。 |
4. 社交相机应用 | 社交相机应用专注于用户之间的分享和互动。它们通常具有内置的社交媒体集成,允许用户轻松地拍摄照片或录制视频,并直接分享到社交平台上。社交相机应用也常常提供滤镜、贴纸、标签等社交化的特性。 |
5. AR相机应用 | AR相机应用结合了增强现实技术和相机功能,可以在相机预览中叠加虚拟物体、场景或效果。它们提供了沉浸式的增强现实体验,允许用户与虚拟内容进行交互、游戏或创作。AR相机应用在娱乐、教育、购物等领域有广泛应用。 |
相机应用的不同类型和分类,包括原生相机应用、第三方相机应用、专业相机应用、社交相机应用和AR相机应用。每种类型的相机应用都具有不同的特点和定位,满足了不同用户的需求和使用场景。
相机应用的架构和组件如下表格所示:
架构和组件 | 描述 |
---|---|
1. 硬件抽象层(HAL) | 相机应用与相机硬件之间的接口层。HAL负责处理底层硬件驱动程序与操作系统之间的通信,提供相机功能的抽象接口,以便上层应用程序能够与不同的相机硬件进行交互。 |
2. 相机服务(Camera Service) | 相机服务是相机应用的核心组件,负责管理相机硬件资源和处理相机功能。它与HAL进行交互,控制相机的打开、关闭、配置和数据传输等操作。相机服务还提供API供上层应用程序调用,实现相机的拍摄、录制、预览等功能。 |
3. 相机框架(Camera Framework) | 相机框架是相机应用的高级组件,提供了更高级别的功能和控制选项。它包括相机API、相机参数设置、图像处理、拍摄模式、拍摄效果等。相机框架通过与相机服务进行交互,实现相机的各种功能和特性。 |
4. 相机界面(Camera UI) | 相机界面是用户与相机应用进行交互的界面部分。它包括预览界面、设置界面、拍摄按钮、拍摄模式切换等。相机界面提供了直观的操作界面,让用户可以调整相机参数、预览图像、拍摄照片或录制视频等。 |
5. 图像处理引擎 | 图像处理引擎负责对相机捕获的图像进行处理和优化。它包括图像算法、滤镜、色彩校正、降噪等。图像处理引擎能够提高图像质量、增强细节、改善色彩和对比度等,让拍摄的照片更加出色。 |
相机应用的架构和组件,包括硬件抽象层(HAL)、相机服务(Camera Service)、相机框架(Camera Framework)、相机界面(Camera UI)和图像处理引擎。这些组件共同协作,实现了相机应用的功能和特性。
1.以高通的骁龙相机中实际需求为例:
2.解决方案:
1.在SDCard.java文件中的getDirectory()方法中设置sd卡的存储路径:
public String getDirectory() {
if (mVolume == null) {
return null;
}
if (mPath == null) {
File[] dirs = mContext.getExternalFilesDirs(null);
if (dirs != null) {
String dir;
for (int i=0; i
2. 在values目录下的bool.xml中将force_count_down_sound设置为true:
false
true
false
3. 在PhotoModule.java中的onKeyDown()方法中的KEYCODE_CAMERA选项中,添加onShutterButtonFocus(true),就可解决该bug:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (CameraUtil.volumeKeyShutterDisable(mActivity)) {
return false;
}
case KeyEvent.KEYCODE_FOCUS:
if (/*TODO: mActivity.isInCameraApp() &&*/ mFirstTimeInitialized) {
if (event.getRepeatCount() == 0) {
onShutterButtonFocus(true);
}
return true;
}
return false;
case KeyEvent.KEYCODE_CAMERA:
if (mFirstTimeInitialized && event.getRepeatCount() == 0) {
//add begin
onShutterButtonFocus(true);
//add end
onShutterButtonClick();
}
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
if ( (mCameraState != PREVIEW_STOPPED) && (mFocusManager != null) &&
(mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING) &&
(mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING_SNAP_ON_FINISH) ) {
if (mbrightness > MINIMUM_BRIGHTNESS) {
mbrightness-=mbrightness_step;
synchronized (mCameraDevice) {
/* Set the "luma-adaptation" parameter */
mParameters = mCameraDevice.getParameters();
mParameters.set("luma-adaptation", String.valueOf(mbrightness));
mCameraDevice.setParameters(mParameters);
}
}
brightnessProgressBar.setProgress(mbrightness);
Editor editor = mPreferences.edit();
editor.putInt(CameraSettings.KEY_BRIGHTNESS, mbrightness);
editor.apply();
brightnessProgressBar.setVisibility(View.INVISIBLE);
mBrightnessVisible = true;
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if ( (mCameraState != PREVIEW_STOPPED) && (mFocusManager != null) &&
(mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING) &&
(mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING_SNAP_ON_FINISH) ) {
if (mbrightness < MAXIMUM_BRIGHTNESS) {
mbrightness+=mbrightness_step;
synchronized (mCameraDevice) {
/* Set the "luma-adaptation" parameter */
mParameters = mCameraDevice.getParameters();
mParameters.set("luma-adaptation", String.valueOf(mbrightness));
mCameraDevice.setParameters(mParameters);
}
}
brightnessProgressBar.setProgress(mbrightness);
Editor editor = mPreferences.edit();
editor.putInt(CameraSettings.KEY_BRIGHTNESS, mbrightness);
editor.apply();
brightnessProgressBar.setVisibility(View.INVISIBLE);
mBrightnessVisible = true;
}
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
// If we get a dpad center event without any focused view, move
// the focus to the shutter button and press it.
if (mFirstTimeInitialized && event.getRepeatCount() == 0) {
// Start auto-focus immediately to reduce shutter lag. After
// the shutter button gets the focus, onShutterButtonFocus()
// will be called again but it is fine.
onShutterButtonFocus(true);
mUI.pressShutterButton();
}
return true;
}
return false;
}
4. 在CameraActivity.java中onPostExecute()方法添加该功能:
@Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap == null) {
//add begin
mThumbnail = (ImageView) findViewById(R.id.preview_thumb);
if (mThumbnail != null) {
// Clear the image resource when the bitmap is invalid.
try {
Drawable appIcon = getPackageManager().getActivityIcon(new ComponentName(
"com.google.android.apps.photosgo", "com.google.android.apps.photosgo.home.HomeActivity"));
mThumbnail.setImageDrawable(appIcon);
mThumbnail.setVisibility(View.VISIBLE);
} catch (PackageManager.NameNotFoundException e) {
mThumbnail.setImageDrawable(null);
mThumbnail.setVisibility(View.GONE);
e.printStackTrace();
}
//add end
}
} else {
updateThumbnail(bitmap);
}
mJpegData = null;
}
5.在PhotoModule.java的onShutterButtonFocus()中判断并设置快门按钮的焦点:
@Override
public void onShutterButtonFocus(boolean pressed) {
if (mCameraDevice == null
|| mPaused || mUI.collapseCameraControls()
|| (mCameraState == SNAPSHOT_IN_PROGRESS)
|| (mCameraState == PREVIEW_STOPPED)
|| (null == mFocusManager)) {
Log.v(TAG, "onShutterButtonFocus error case mCameraState = " + mCameraState
+ "mCameraDevice = " + mCameraDevice + "mPaused =" + mPaused);
return;
}
synchronized(mCameraDevice) {
if (mCameraState == LONGSHOT) {
mLongshotActive = false;
mCameraDevice.setLongshot(false);
mUI.animateCapture(mLastJpegData);
mLastJpegData = null;
if (!mFocusManager.isZslEnabled()) {
setupPreview();
} else {
setCameraState(IDLE);
mFocusManager.resetTouchFocus();
if (CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE.equals(
mFocusManager.getFocusMode())) {
mCameraDevice.cancelAutoFocus();
}
mUI.resumeFaceDetection();
}
}
}
// Do not do focus if there is not enough storage.
if (pressed && !canTakePicture()) return;
if (pressed) {
mFocusManager.onShutterDown();
} else {
// for countdown mode, we need to postpone the shutter release
// i.e. lock the focus during countdown.
if (!mUI.isCountingDown()) {
mFocusManager.onShutterUp();
}
}
//add begin
if(PhotoUI.mThumbnail != null)
PhotoUI.mThumbnail.setFocusable(false);
if(PhotoUI.mMenuButton != null)
PhotoUI.mMenuButton.setFocusable(false);
if(PhotoUI.mSwitcher != null)
PhotoUI.mSwitcher.setFocusable(false);
if(PhotoUI.mFrontBackSwitcher != null)
PhotoUI.mFrontBackSwitcher.setFocusable(false);
if(PhotoUI.mShutterButton != null){
PhotoUI.mShutterButton.setFocusedByDefault(true);
PhotoUI.mShutterButton.setFocusable(true);
PhotoUI.mShutterButton.setFocusableInTouchMode(true);
PhotoUI.mShutterButton.requestFocus();
}
//add end
}
6. 在VideoModule.java中的子线程中设置前后摄按钮的焦点:
Handler mSetViewFocusHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
if(VideoUI.mThumbnail != null)
VideoUI.mThumbnail.setFocusable(true);
if(VideoUI.mPauseButton != null)
VideoUI.mPauseButton.setFocusable(true);
if(VideoUI.mMuteButton != null)
VideoUI.mMuteButton.setFocusable(true);
//add begin
if(VideoUI.mFrontBackSwitcher != null)
VideoUI.mFrontBackSwitcher.setFocusable(true);
//add end
//if(VideoUI.mSurfaceView != null)
// VideoUI.mSurfaceView.setFocusable(true);
break;
case 2:
if(VideoUI.mThumbnail != null)
VideoUI.mThumbnail.setFocusable(true);
if(VideoUI.mPauseButton != null)
VideoUI.mPauseButton.setFocusable(true);
if(VideoUI.mMuteButton != null)
VideoUI.mMuteButton.setFocusable(true);
//add begin
if(VideoUI.mFrontBackSwitcher != null)
VideoUI.mFrontBackSwitcher.setFocusable(true);
//add end
// if(VideoUI.mSurfaceView != null)
// VideoUI.mSurfaceView.setFocusable(true);
if(VideoUI.mMenuButton != null)
VideoUI.mMenuButton.setFocusable(true);
if(VideoUI.mSwitcher != null)
VideoUI.mSwitcher.setFocusable(true);
break;
default:
break;
}
};
};
7. 在PermissionsActivity.java中的onRequestPermissionsResult()将获取权限失败后的弹窗给finish()掉:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
if (mShouldRequestCameraPermission) {
if ((grantResults.length >= mIndexPermissionRequestCamera + 1) &&
(grantResults[mIndexPermissionRequestCamera] ==
PackageManager.PERMISSION_GRANTED)) {
mFlagHasCameraPermission = true;
} else {
mCriticalPermissionDenied = true;
}
}
if (mShouldRequestMicrophonePermission) {
if ((grantResults.length >= mIndexPermissionRequestMicrophone + 1) &&
(grantResults[mIndexPermissionRequestMicrophone] ==
PackageManager.PERMISSION_GRANTED)) {
mFlagHasMicrophonePermission = true;
} else {
mCriticalPermissionDenied = true;
}
}
if (mShouldRequestStoragePermission) {
if ((grantResults.length >= mIndexPermissionRequestStorageRead + 1) &&
(grantResults[mIndexPermissionRequestStorageWrite] ==
PackageManager.PERMISSION_GRANTED) &&
(grantResults[mIndexPermissionRequestStorageRead] ==
PackageManager.PERMISSION_GRANTED)) {
mFlagHasStoragePermission = true;
} else {
mCriticalPermissionDenied = true;
}
}
if (mShouldRequestLocationPermission) {
if ((grantResults.length >= mIndexPermissionRequestLocation + 1) &&
(grantResults[mIndexPermissionRequestLocation] ==
PackageManager.PERMISSION_GRANTED)) {
// Do nothing
} else {
// Do nothing
}
}
if (mFlagHasCameraPermission && mFlagHasMicrophonePermission &&
mFlagHasStoragePermission) {
handlePermissionsSuccess();
} else if (mCriticalPermissionDenied) {
// modify begin
// handlePermissionsFailure();
finish();
//modify end
}
}
参考了Google API中关于Camera的介绍
要访问摄像头,使用相机和自动对焦功能,则清单文件里应包括以下内容:
1.拍照流程要使用到以下的类并且按步骤进行:
2.视频录制模式的相关步骤:
本文仅代表个人观点和经验,难免存在不足之处。如果有任何错误或改进的建议,欢迎指正和交流,共同进步。