Android应用提供了Camera来控制拍照,使用Camera进行拍照的步骤如下:

1、调用Camera的open()方法打开相机。

2、调用Camera的getParameters()方法获取拍照参数,该方法返回一个Camera.Parameters对象。

3、调用Camera的startPreview()方法开始预览取景,在预览取景之前需要调用Camera的setPreviewDisplay(SurfaceHolder  holder)方法设置使用哪个SurfaceView来显示取景图片。

4、调用Camera的setParameters(),并将Camera.Parameters对象作为参数传入,这样即可对相机的拍照参数进行控制。

5、调用Camera的startPreview()方法开始预览取景,在预览取景之前调用Camera的setPreviewDisplay(SurfaceHolder  holder)方法设置使用哪个SurfaceView来显示取景图片。

6、调用Camera的takePicture()方法进行拍照。

7、结束程序时,调用Camera的stopPreview()结束取景预览,并调用release()方法释放资源。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream.PutField;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.view.Display;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;

public class CaptureImage extends Activity {
  SurfaceView sView;
  SurfaceHolder surfaceHolder;
  int screenWidth;
  int screenHeight;
  //定义系统使用的照相机
  Camera camera;
  //是否在浏览中
  boolean isPreiew = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //设置全屏
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_capture_image);
    WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    Paint size = new Paint();
    Display display = wm.getDefaultDisplay();
    //获取屏幕的宽和高
    screenWidth = display.getWidth();
    screenHeight = display.getHeight();
    //获取界面中的SurfaceView组件
    sView = (SurfaceView) findViewById(R.id.sView);
    //获得SurfaceView的SurfaceHolder
    surfaceHolder = sView.getHolder();
    //为SurfaceHolder添加一个回调的监听器
    surfaceHolder.addCallback(new Callback() {

      @Override
      public void surfaceDestroyed(SurfaceHolder holder) {
        // 如果Camera不为null,释放摄像头
        if(camera != null){
          if(isPreiew){
            camera.stopPreview();
          }
          camera.release();
          camera = null;
        }
      }

      @Override
      public void surfaceCreated(SurfaceHolder holder) {
        // 打开摄像头
        initCamera();
      }

      @Override
      public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                  int height) {
      }
    });
    //设置该SurfaceView自己不维护缓冲
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  }

  private void initCamera(){
    if(!isPreiew){
      camera = Camera.open();
    }
    if(camera != null && !isPreiew){
      try {
        Camera.Parameters parameters = camera.getParameters();
        //设置预览照片的大小
        parameters.setPreviewSize(screenWidth, screenHeight);
        //每秒显示4帧
        parameters.setPreviewFrameRate(4);
        //设置图片格式
        parameters.setPictureFormat(PixelFormat.JPEG);
        //设置JPG照片的质量
        parameters.set("jpeg-quality", 85);
        //设置照片的大小
        parameters.setPictureSize(screenWidth, screenHeight);
        camera.setParameters(parameters);
        //通过SurfaceView显示取景画面
        camera.setPreviewDisplay(surfaceHolder);
        //开始预览
        camera.startPreview();
        //自动对焦
        camera.autoFocus(null);
      } catch (Exception e) {
        e.printStackTrace();
      }
      isPreiew = true;

    }
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {
      //当用户单击照相键、中央键时执行拍照
      case KeyEvent.KEYCODE_DPAD_CENTER:
      case KeyEvent.KEYCODE_CAMERA:
        if(camera != null && event.getRepeatCount() == 0){
          //拍照
          camera.takePicture(null, null, myjpegCallback);
          return true;
        }
        break;
    }
    return super.onKeyDown(keyCode, event);
  }

  PictureCallback myjpegCallback = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
      // 根据拍照所得的数据创建位图
      final Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);
      //加载/layout.save.xml文件对应的布局资源
      View saveDialog = getLayoutInflater().inflate(R.layout.save, null);
      final EditText phoneName = (EditText) saveDialog.findViewById(R.id.phone_name);
      ImageView show = (ImageView) saveDialog.findViewById(R.id.show);
      //显示刚刚拍得的照片
      show.setImageBitmap(bm);
      //使用对话框显示saveDialog组件
      new AlertDialog.Builder(CaptureImage.this).setView(saveDialog)
          .setPositiveButton("保存!", new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {
          // 创建一个位于SD卡上的文件
          File file = new File(Environment.getExternalStorageDirectory(),phoneName.getText().toString()+".jpg");
          FileOutputStream outStream = null;
          try {
            //打开指定文件对应的输出流
            outStream = new FileOutputStream(file);
            //把位图输出到指定文件中
            bm.compress(CompressFormat.JPEG, 100, outStream);
            outStream.close();
          } catch (FileNotFoundException e) {
            e.printStackTrace();
          } catch (IOException e) {
            e.printStackTrace();
          }

        }
      }).setNegativeButton("取消",null).show();
      //重新浏览
      camera.stopPreview();
      camera.startPreview();
      isPreiew = true;
    }
  };

}

Android模拟器不会使用宿主机上的摄像头作为相机镜头,当用户进行拍照时,系统将会使用一张已有的图片作为相片。

运行该程序需要获得相机拍照的权限,因此需要在AndroidManifest.xml文件中增加如下代码片段进行授权:

<!-- 授权程序使用摄像头的权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>

使用Camera进行拍照的更多相关文章

  1. Android Camera进行拍照

    Android应用提供了Camera来控制拍照,使用Camera进行拍照的步骤: 1.调用Camera的open()方法打开相机. 2.调用Camera的getParameters()方法获取拍照参数 ...

  2. Android之Camera控制拍照

    package com.android.xiong.cameratest; import java.io.File; import java.io.FileOutputStream; import j ...

  3. 通过Camera进行拍照

    Android通过Camera来控制拍照,使用Camera比较简单,按步骤进行即可: 下面用一个示例来演示: Activity: package com.home.activity; import j ...

  4. Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能

    Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...

  5. 使用Camera进行拍照 & 后台静默拍照的思路

    Android中的Camera可以用来进行自定义相机.取景框实时预览.拍照等操作.在5.0中,这个类不推荐使用了,新出了一个Camera2,那个东西没怎么研究过,反正一时半会用不到.本篇讲解的是如果用 ...

  6. 玩转Android Camera开发(二):使用TextureView和SurfaceTexture预览Camera 基础拍照demo

    Google自Android4.0出了TextureView,为什么推出呢?就是为了弥补Surfaceview的不足,另外一方面也是为了平衡GlSurfaceView,当然这是本人揣度的.关于Text ...

  7. 玩转Android Camera开发(一):Surfaceview预览Camera,基础拍照功能完整demo

    杂家前文是在2012年的除夕之夜仓促完成,后来很多人指出了一些问题,琐事缠身一直没有进行升级.后来随着我自己的使用,越来越发现不出个升级版的demo是不行了.有时候就连我自己用这个demo测一些性能. ...

  8. Android Camera开发:使用TextureView和SurfaceTexture预览Camera 基础拍照demo

    Google自Android4.0出了TextureView,为什么推出呢?就是为了弥补Surfaceview的不足,另外一方面也是为了平衡GlSurfaceView,当然这是本人揣度的.关于Text ...

  9. Android Camera开发:使用GLSurfaceView预览Camera 基础拍照

    GLSurfaceView是OpenGL中的一个类,也是可以预览Camera的,而且在预览Camera上有其独到之处.独到之处在哪?当使用Surfaceview无能为力.痛不欲生时就只有使用GLSur ...

随机推荐

  1. iOS - OC NSCache 缓存

    前言 NSCache 是苹果提供的一个专门用来做缓存的类,当内存 "不足" 或超过限制的时候,会自动清理缓存,使用时可以指定缓存的数量和成本.用法与 NSMutableDictio ...

  2. iOS - Swift 数据持久化

    1.Sandbox 沙箱 iOS 为每个应用提供了独立的文件空间,一个应用只能直接访问为本应用分配的文件目录,不可以访问其他目录,每个应用自己独立的访问空间被称为该应用的沙盒.也就是说,一个应用与文件 ...

  3. [转载] C++ STL string的Copy-On-Write技术

    原文: http://coolshell.cn/articles/12199.html stl的string是经过严格优化的, 深入理解对以后编程过程中应用string非常有益处, 感谢左耳朵耗子的精 ...

  4. hdu 1081(最大子矩阵和)

    题目很简单,就是个最大子矩阵和的裸题,看来算法课本的分析后也差不多会做了.利用最大子段和的O(n)算法,对矩阵的行(或列)进行 i和j的枚举,对于第 i到j行,把同一列的元素进行压缩,得到一整行的一维 ...

  5. 转:switch内部的变量定义问题(goto类似)

    自我总结:(之前查过goto和switch的资料但是一直没有搞懂,直到今天看到这个讨论才懂了) 1   int a;    是个描述,而不是个命令,只是说明我需要空间,编译器会保证在相应的作用域之中这 ...

  6. maven相关资料

    http://www.yiibai.com/maven/ Maven教程 https://www.zhihu.com/question/20104270 http://huangnx.com/tags ...

  7. 激活MyEclipse 6.5方法-通过一段Java程序生成激活码

    在MyEclipse中新建一个Java类,名为MyEclipseKeyGen,将下面的Java代码拷贝到MyEclipseKeyGen类中,先修改变量subscriber的值,然后运行程序即可获得Su ...

  8. 利用php的序列化和反序列化来做简单的数据本地存储

    利用php的序列化和反序列化来做简单的数据本地存储 如下程序可以做为一个工具类 /** * 利用php的序列化和反序列化来做简单的数据本地存储 */ class objectdb { private ...

  9. screenX clientX pageX的区别

    screenX:鼠标位置相对于用户屏幕水平偏移量,而screenY也就是垂直方向的,此时的参照点也就是原点是屏幕的左上角. clientX:跟screenX相比就是将参照点改成了浏览器内容区域的左上角 ...

  10. iOS项目的目录结构和开发流程

    转自无网不剩的博客 网上相关的资源不多,开源的且质量还不错的iOS项目也是少之又少,最近正好跟同事合作了一个iOS项目,来说说自己的一些想法.   目录结构 AppDelegate Models Ma ...