链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/06/2382679.html
一、概述
Camera是手机的一个很重要的设备,可以说现在的每一部手机上都有。回想当时在Linux搞摄像头编程真的要捏一把汗。有人会说在Linux下装个opencv就可以通过它的函数来使用摄像头啦,但我并没有这么做,我还是用最原始的方法(V4L2)实现了。之前研究过Android关于摄像头这部分的源码,毫无疑问,Android关于摄像头底层的实现用的也是V4L2。
二、实现
新建工程MyCamera,修改/res/layout/main.xml文件,使用RelativeLayout布局,并添加一个SurfaceView和一个Button,完整的main.xml如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:orientation="vertical" 6 > 7 8 <SurfaceView 9 android:id="@+id/surfaceview"10 android:layout_width="fill_parent"11 android:layout_height="wrap_content"12 android:layout_alignParentTop="true"13 android:layout_above="@+id/button"14 />15 16 <Button 17 android:id="@+id/button"18 android:layout_width="fill_parent"19 android:layout_height="wrap_content"20 android:layout_alignParentBottom="true"21 android:text="拍照"22 />23 24 </RelativeLayout>
接着,修改MyCameraActivity.java文件,实现了SurfaceHolder.Callback接口,用于初始化、释放摄像头和Camera.PictureCallback接口,用于保存图片数据到文件里。完整的内容如下:
1 package com.nan.camera; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 8 import android.app.Activity; 9 import android.graphics.Bitmap; 10 import android.graphics.BitmapFactory; 11 import android.graphics.PixelFormat; 12 import android.hardware.Camera; 13 import android.os.Bundle; 14 import android.os.Environment; 15 import android.view.SurfaceHolder; 16 import android.view.SurfaceView; 17 import android.view.View; 18 import android.widget.Button; 19 import android.widget.Toast; 20 21 public class MyCameraActivity extends Activity 22 { 23 private SurfaceView mSurfaceView = null; 24 private SurfaceHolder mSurfaceHolder = null; 25 private Button takePictureButton = null; 26 private Camera mCamera; 27 //记录保存的是第几张图片 28 private int whichPicture = 0; 29 30 /** Called when the activity is first created. */ 31 @Override 32 public void onCreate(Bundle savedInstanceState) 33 { 34 super.onCreate(savedInstanceState); 35 setContentView(R.layout.main); 36 37 takePictureButton = (Button)this.findViewById(R.id.button); 38 mSurfaceView = (SurfaceView)this.findViewById(R.id.surfaceview); 39 mSurfaceHolder = mSurfaceView.getHolder(); 40 mSurfaceHolder.addCallback(new SurfaceHolderCallback()); 41 //设置缓冲区类型 42 mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 43 //拍照按钮监听 44 takePictureButton.setOnClickListener(new View.OnClickListener() 45 { 46 47 @Override 48 public void onClick(View v) 49 { 50 // TODO Auto-generated method stub 51 //拍照 52 mCamera.takePicture(null, null, pictureCallback); 53 } 54 }); 55 56 } 57 58 private class SurfaceHolderCallback implements SurfaceHolder.Callback 59 { 60 61 @Override 62 public void surfaceChanged(SurfaceHolder holder, int format, int width, 63 int height) { 64 // TODO Auto-generated method stub 65 66 } 67 68 @Override 69 public void surfaceCreated(SurfaceHolder holder) 70 { 71 // TODO Auto-generated method stub 72 //打开摄像头 73 mCamera = Camera.open(); 74 try { 75 mCamera.setPreviewDisplay(mSurfaceHolder); 76 } catch (IOException e) { 77 // TODO Auto-generated catch block 78 e.printStackTrace(); 79 } 80 //获取摄像头参数 81 Camera.Parameters mParameters = mCamera.getParameters(); 82 //设置图片格式 83 mParameters.setPictureFormat(PixelFormat.JPEG); 84 mCamera.setParameters(mParameters); 85 //开始预览 86 mCamera.startPreview(); 87 } 88 89 @Override 90 public void surfaceDestroyed(SurfaceHolder holder) 91 { 92 // TODO Auto-generated method stub 93 if(mCamera!=null) 94 { 95 //停止预览 96 mCamera.stopPreview(); 97 //释放摄像头 98 mCamera.release(); 99 mCamera = null;100 }101 }102 103 }104 105 //拍照回调106 private Camera.PictureCallback pictureCallback = new Camera.PictureCallback()107 {108 109 @Override110 public void onPictureTaken(byte[] data, Camera camera) 111 {112 // TODO Auto-generated method stub113 //停止预览114 mCamera.stopPreview();115 Bitmap mBitmap;116 mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);117 //文件路径和文件名118 File pictureFile = new File(Environment.getExternalStorageDirectory(),"camera"+Integer.toString(whichPicture)+".jpg"); 119 120 try 121 {122 FileOutputStream mFileOutputStream = new FileOutputStream(pictureFile);123 //将图像数据压入文件124 mBitmap.compress(Bitmap.CompressFormat.JPEG, 75, mFileOutputStream);125 try {126 //关闭输出流127 mFileOutputStream.close();128 } catch (IOException e) {129 // TODO Auto-generated catch block130 e.printStackTrace();131 }132 } 133 catch (FileNotFoundException e) 134 {135 // TODO Auto-generated catch block136 e.printStackTrace();137 } 138 displayToast("保存成功!");139 whichPicture++;140 //开始预览141 mCamera.startPreview();142 }143 144 }; 145 146 //显示Toast函数147 private void displayToast(String s)148 {149 Toast.makeText(this, s, Toast.LENGTH_SHORT).show();150 }151 152 }
在真机上运行该程序:
按一下“拍照”按钮:
图片会被保存到sd卡的根目录下面。
时间: 2024-08-03 22:49:27