android 多媒体和相机详解七

本文介绍如何创建一个基本的相机预览类,并将其整合到应用程序布局中,以便用户能够查看实时摄像头画面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建一个预览类

为了让用户有效的获取图像和视频,必须能让他们看到相机中的影像。一个相机预览类是一个SurfaceView类,它可以显示相机中的实时影像,于是用户就可以框住并捕获图像或视频。


下面例子中的代码演示了如何创建一个基本的相机预览类,此类可以被一个viewlayout包含。此类实现了SurfaceHolder.Callback,为的是获取创建和销毁view的回调事件,这个view用来分配相机预览输入。

  1. /** 一个基本的相机预览类 */ 
  2. public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
  3.     private SurfaceHolder mHolder; 
  4.     private Camera mCamera; 
  5.  
  6.     public CameraPreview(Context context, Camera camera) { 
  7.         super(context); 
  8.         mCamera = camera; 
  9.  
  10.         // 安装一个SurfaceHolder.Callback,于是当下层的界面被创建或销毁时我们可以得到通知 
  11.         mHolder = getHolder(); 
  12.         mHolder.addCallback(this); 
  13.         // 过时的设置,但是android3.0之前的版本需要。 
  14.         mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
  15.     } 
  16.  
  17.     public void surfaceCreated(SurfaceHolder holder) { 
  18.         // 界面被创建了,现在告诉相机何时画 preview. 
  19.         try
  20.             mCamera.setPreviewDisplay(holder); 
  21.             mCamera.startPreview(); 
  22.         } catch (IOException e) { 
  23.             Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
  24.         } 
  25.     } 
  26.  
  27.     public void surfaceDestroyed(SurfaceHolder holder) { 
  28.         // 空的。在你的activity中注意释放相机预览。 
  29.     } 
  30.  
  31.     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
  32.         //如果你的预览可以改变或旋转,小心这里这些事件们。 
  33.         // 保证在改变大小或改变格式之前停止预览。 
  34.         if (mHolder.getSurface() == null){ 
  35.           // 预览界面不存在 
  36.           return
  37.         } 
  38.  
  39.         // 改变之前停止预览 
  40.         try
  41.             mCamera.stopPreview(); 
  42.         } catch (Exception e){ 
  43.           // ignore: tried to stop a non-existent preview 
  44.         } 
  45.  
  46.         // 设置预览尺寸并且执行所有大小改变,旋转或格式改变等。 
  47.  
  48.         // 开始使用新的设置预览。 
  49.         try
  50.             mCamera.setPreviewDisplay(mHolder); 
  51.             mCamera.startPreview(); 
  52.  
  53.         } catch (Exception e){ 
  54.             Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
  55.         } 
  56.     } 

如果你想为你的相机预览设置一个尺寸,就应在surfaceChanged()方法中进行。当设置预览尺寸时,你必须使用getSupportedPreviewSizes()来获取正确的尺寸值。不能使用setPreviewSize()设置任意的尺寸值。


将预览view放到layout

一个相机预览类,比如前面例子中所示的,必须与其它用户界面控件一起放到layout中来获取图像或视频。本节向你演示如何为预览建立一个基本的layoutactivity

下面的layout代码提供了一个十分基础的view,这个view可以显示一个相机预览.在此例子中,FrameLayout元素是相机预览类的容器.使用layout类型是为了另外的图像信息或控制控件可以覆盖在预览图像之上显示.

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:orientation="horizontal" 
  4.     android:layout_width="fill_parent" 
  5.     android:layout_height="fill_parent" 
  6.     > 
  7.   <FrameLayout 
  8.     android:id="@+id/camera_preview" 
  9.     android:layout_width="fill_parent" 
  10.     android:layout_height="fill_parent" 
  11.     android:layout_weight="1" 
  12.     /> 
  13.  
  14.   <Button 
  15.     android:id="@+id/button_capture" 
  16.     android:text="Capture" 
  17.     android:layout_width="wrap_content" 
  18.     android:layout_height="wrap_content" 
  19.     android:layout_gravity="center" 
  20.     /> 
  21. </LinearLayout> 

  在多数设备上,相机预览图像的方向是横的.上面的layout例子中指定了横向的layout.为了简单地显示相机预览,你应该在你的manifest中指定你的应用的activity的方向也为横向.

  1. <activity android:name=".CameraActivity" 
  2.           android:label="@string/app_name" 
  3.  
  4.           android:screenOrientation="landscape"> 
  5.           <!-- configure this activity to use landscape orientation --> 
  6.  
  7.           <intent-filter> 
  8.         <action android:name="android.intent.action.MAIN" /> 
  9.         <category android:name="android.intent.category.LAUNCHER" /> 
  10.     </intent-filter> 
  11. </activity> 

  注:相机预览不是必须为横向的.从Android2.2 (API Level8)开始,你可以使用setDisplayOrientation()方法来设置预览图像的旋转.为了改变预览方向以与当前设备的方向相同,在你的预览类的surfaceChanged()方法中,先调用Camera.stopPreview()停止预览,再改变方向,然后使用Camera.startPreview()重新启动预览.


  在你用于相机viewactivity中,添加你的预览类到上面例子中的FrameLayout元素中.你的相机activity必须在其paused或关闭时确保释放相机对象.下面的例子演示了如何修改一个相机activity来附加一个预览类.

  1. public class CameraActivity extends Activity { 
  2.     private Camera mCamera; 
  3.     private CameraPreview mPreview; 
  4.  
  5.     @Override 
  6.     public void onCreate(Bundle savedInstanceState) { 
  7.         super.onCreate(savedInstanceState); 
  8.         setContentView(R.layout.main); 
  9.  
  10.         // Create an instance of Camera 
  11.         mCamera = getCameraInstance(); 
  12.  
  13.         // Create our Preview view and set it as the content of our activity. 
  14.         mPreview = new CameraPreview(this, mCamera); 
  15.         FrameLayout preview = (FrameLayout) findViewById(id.camera_preview); 
  16.         preview.addView(mPreview); 
  17.     } 

注:此例中的getCameraInstance()方法引用自"使用相机"一节的同名方法.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值