• Android开发中如何调用摄像头的功能


    我们要调用摄像头的拍照功能,显然
    第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在SD卡中,必须加入SD卡读写权限,所以第一步,我们应该在Android清单文件中加入以下代码
        <uses-permission android:name="android.permission.CAMERA"/>//摄像头权限
        SD卡读写权限
        <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    第二步,要将摄像头捕获的图像实时地显示在手机上。
    我们是用SurfaceView这个视图组件来实现的,因此在main.xml中加入下列代码
    <SurfaceView  
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:id="@+id/surfaceview"
     />
    第三步,设置窗口的显示方式
        首先获得当前窗口 Window window = getWindow();//得到窗口
        接着设置没有标题 requestWindowFeature(Window.FEATURE_NO_TITLE);//没有标题
        接着设置全屏 window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
            WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏
        当然,我们在拍照过程中,屏幕必须一致处于高亮状态,因此接着加入下面代码
       window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//设置高亮
    至此,我们将窗口的显示方式规定死了,然后才能设置窗口上显示的组件(顺序非常重要)
     setContentView(R.layout.main);
    第四步,设置SurficeView显示控件的属性
       找到surficeView
       surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
       设置它的像素为800x600
       surfaceView.getHolder().setFixedSize(800, 480);
      //下面设置surfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前
            surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    第五步,就是为surficeView加入回调方法(callBack)
    surfaceView.getHolder().addCallback(new SurfaceCallback());
    上面的回调类是我们自己定义的,代码如下
    private class SurfaceCallback implements SurfaceHolder.Callback{
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    try {
    camera = Camera.open();//打开硬件摄像头,这里导包得时候一定要注意是android.hardware.Camera
    WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);//得到窗口管理器
    Display display  = wm.getDefaultDisplay();//得到当前屏幕
    Camera.Parameters parameters = camera.getParameters();//得到摄像头的参数
    parameters.setPreviewSize(display.getWidth(), display.getHeight());//设置预览照片的大小
    parameters.setPreviewFrameRate(3);//设置每秒3帧
    parameters.setPictureFormat(PixelFormat.JPEG);//设置照片的格式
    parameters.setJpegQuality(85);//设置照片的质量
    parameters.setPictureSize(display.getHeight(), display.getWidth());//设置照片的大小,默认是和     屏幕一样大
    camera.setParameters(parameters);
    camera.setPreviewDisplay(surfaceView.getHolder());//通过SurfaceView显示取景画面
    camera.startPreview();//开始预览
    isPreview = true;//设置是否预览参数为真
    } catch (IOException e) {
    Log.e(TAG, e.toString());
    }
    }
     
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
    int height) {
    // TODO Auto-generated method stub
    }
                   
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    if(camera!=null){
    if(isPreview){//如果正在预览 
    camera.stopPreview();
    camera.release();
    }
    }
    }
       
        }
    第六步,我们必须对按键事件进行监听,如是拍照还是聚焦,代码如下
    public boolean onKeyDown(int keyCode, KeyEvent event) {//处理按键事件
    if(camera!=null&&event.getRepeatCount()==0)//代表只按了一下
    {
    switch(keyCode){
    case KeyEvent.KEYCODE_BACK://如果是搜索键
         camera.autoFocus(null);//自动对焦
      break;
       case KeyEvent.KEYCODE_DPAD_CENTER://如果是中间键
         camera.takePicture(null, null, new TakePictureCallback());//将拍到的照片给第三个对象中,这里的TakePictureCallback()是自己定义的,在下面的代码中
     break;
    }
    }
    return true;//阻止事件往下传递,否则按搜索键会变成系统默认的
    }
    ------------------------------------------------------------------------------------------
    private final class TakePictureCallback implements PictureCallback{
    public void onPictureTaken(byte[] data, Camera camera) {
    try {
    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
    File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
    FileOutputStream outputStream = new FileOutputStream(file);
    bitmap.compress(CompressFormat.JPEG, 100, outputStream);
    outputStream.close();
    camera.stopPreview();
    camera.startPreview();//处理完数据之后可以预览
    } catch (Exception e) {
    Log.e(TAG, e.toString());
    }
    }
    }
    注意,代码中有两个回调类,一个是SurfaceCallback(),另外一个是TakePictureCallback(),初学者可能一时难以理解,通俗地讲,前者是用来监视surficeView这个暂时存放图片数据的显示控件的,根据它的显示情况调用不同的方法,包括surfaceCreated(),surfaceChanged(),surfaceDestroyed(),也就不难理解为什么会有这三个回调方法了(注意,在surfaceDestroyed()方法中必须释放摄像头,详细代码参见上方)。TakePictureCallback()是为了监视是否拍照而设计的接口,期中也仅有一个方法,camera将拍照得到的数据传入方法,我们便可以对拍照得到的数据进行进一步处理了。
    至此,简单的拍照功能介绍完毕!
     
     
     
     
    package cn.camera.rxm;
     
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Calendar;
    import java.util.Locale;
     
    import org.apache.commons.logging.Log;
     
    import android.text.format.DateFormat;
    import android.util.*;
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.CompressFormat;
    import android.graphics.BitmapFactory;
    import android.graphics.PixelFormat;
    import android.hardware.Camera;
    import android.hardware.Camera.PictureCallback;
    import android.os.Bundle;
    import android.os.Environment;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    //import android.widget.Toast;
     
     
     
     
    public class MycamActivity extends Activity {
       
    private Preview mPreview;
    private Camera mCamera;
    Bitmap CameraBitmap;
    SurfaceHolder mHolder;
    private static final int OPTION_SNAPSHOT = 0;
    private static final int OPTION_STOPCAMERA = 1;
    private View viewStart;
        @Override
        
        
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            LayoutInflater flater = this.getLayoutInflater();
            viewStart = flater.inflate(R.layout.main, null);
            setContentView(viewStart);
            
            Button btn1 = (Button)findViewById(R.id.button1);
            
            btn1.setOnClickListener(
            new OnClickListener(){
            public void onClick(View v){
           
            mPreview = new Preview(getBaseContext());
            setContentView(mPreview);  
            };
            }
            );
        }
        
        
        public boolean onCreateOptionsMenu(Menu menu){
    //
    menu.add(0, OPTION_SNAPSHOT, 0, R.string.take);
    //
    menu.add(0, OPTION_STOPCAMERA, 1, R.string.back);
    //
    return true;//super.onCreateOptionsMenu(menu);
    }
    public boolean onOptionsItemSelected(MenuItem item) {
    //
     
    int itemId = item.getItemId();
    //
    switch(itemId){
    case OPTION_SNAPSHOT:
    //拍摄照片
    mCamera.takePicture(null, null, jpegCallback);
    try {
    Thread.sleep(4000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    mCamera.startPreview();
    break;
    case OPTION_STOPCAMERA:
     
    mPreview = null;  
    setContentView(viewStart); 
    break;
    }
     
    return true;
    }
    private PictureCallback jpegCallback = new PictureCallback(){
     
    //
    public void onPictureTaken(byte[] data, Camera camera) {
     
    try {
    String name = new DateFormat().format("yyyyMMdd_hhmmss",
    Calendar.getInstance(Locale.CHINA)) + ".jpg";
    FileOutputStream fileout = new FileOutputStream("/mnt/sdcard/sdcard/DCIM/"+ name);
    System.out.println(name);
    fileout.write(data,0,data.length);
    fileout.flush();
    fileout.close();
    } catch (IOException e) {
    // TODO: handle exception
    System.out.println(e);
    }
     
    }
    };
    class Preview extends SurfaceView implements SurfaceHolder.Callback
    {
    Preview(Context context)
    {
    super(context);
    mHolder=getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
    public void surfaceCreated(SurfaceHolder holder)
    {
    mCamera=Camera.open();
    try
    {
    mCamera.setPreviewDisplay(holder);
    }
    catch(IOException exception)
    {
    mCamera.release();
    mCamera=null;
    }
    }
    public void surfaceDestroyed(SurfaceHolder holder)
    {
    mCamera.stopPreview();
    mCamera.release();
    }
     
     
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // TODO Auto-generated method stub
    Camera.Parameters parameters=mCamera.getParameters();
    parameters.setPictureFormat(PixelFormat.JPEG);
    parameters.setPreviewSize(1024, 1024);
     
    mCamera.setParameters(parameters);
    mCamera.setDisplayOrientation(90);
    mCamera.startPreview();
    }
    }
    }
     
     
     
     
     
     
     
  • 相关阅读:
    mac Navicat连接Oracle报错ORA-21561: OID generation failed
    svn: E230001: Server SSL certificate verification failed: certificate issued
    mac删除系统应用出现mac Read-Only filesystem
    spring boot项目03:阅读启动源码
    spring boot项目02:Web项目(基础)
    spring boot项目01:非Web项目(基础)
    idea 单独引入jar_Iidea 单独引入jar_Intellij IDEA 添加jar包的三种方式ntellij IDEA 添加jar包的三种方式
    java输出pdf的依赖包,非maven,包名:spire.pdf.jar 下载
    IDEA Error:java: 无效的源发行版: 11错误
    SpringBoot官网以下载模板方式创建
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5644151.html
Copyright © 2020-2023  润新知