通过Camera进行拍照
Android通过Camera来控制拍照,使用Camera比较简单,按步骤进行即可:
下面用一个示例来演示:
Activity:
package com.home.activity; import java.io.File; import java.io.FileOutputStream; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.res.Configuration; 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.Parameters; import android.hardware.Camera.PictureCallback; import android.os.Bundle; import android.os.Environment; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import com.home.camera.R; public class TestCameraActivity extends Activity { private SurfaceView sView; private SurfaceHolder sHolder; // 屏幕宽和高 private int screenWidth, screenHeight; // 定义系统所用的照相机 private Camera camera; // 摄像头是否已经在预览状态. true:预览状态 ;false:没有预览状态 private boolean isPreview; private Button playBtn; @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.main); WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); // 获取屏幕的宽和高 screenWidth = wm.getDefaultDisplay().getWidth(); screenHeight = wm.getDefaultDisplay().getHeight(); playBtn = (Button) findViewById(R.id.main_btn); // 获取界面中的SurfaceView组件 sView = (SurfaceView) findViewById(R.id.main_sView); // 获取SurfaceView的SurfaceHolder sHolder = sView.getHolder(); // 为sHolder添加一个回调监听器 sHolder.addCallback(new Callback() { @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { // 打开并初始化摄像头 initCamera(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 如果camera不为null,释放摄像头 if (camera != null) { if (isPreview) { camera.stopPreview(); camera.release(); camera = null; } } } }); // 设置SurfaceView自己不维护缓冲区 sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } /** * 初始化摄像头 */ private void initCamera() { if (!isPreview) { camera = Camera.open(); } if (camera != null && !isPreview) { try { Parameters parameters = camera.getParameters(); // 设置闪光灯为自动状态 parameters.setFlashMode(Parameters.FLASH_MODE_AUTO); camera.setParameters(parameters); // 设置预览照片的大小 parameters.setPreviewSize(screenWidth, screenHeight); // 设置每秒显示4帧 parameters.setPreviewFrameRate(4); // 设置图片格式 parameters.setPictureFormat(PixelFormat.JPEG); // 设置JPG照片的质量 parameters.set("jpeg-quality", 85); // 设置照片大小 parameters.setPictureSize(screenWidth, screenHeight); // 通过SurfaceView显示取景画面 camera.setPreviewDisplay(sHolder); // 如果是竖屏 if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { camera.setDisplayOrientation(90); } else { camera.setDisplayOrientation(0); } // 开始预览 camera.startPreview(); // 自动对焦 camera.autoFocus(null); isPreview = true; } catch (Exception e) { e.printStackTrace(); } } playBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (camera != null) { // 拍照 camera.takePicture(null, null, myjpegCallback); } } }); } PictureCallback myjpegCallback = new PictureCallback() { @Override public void onPictureTaken(final byte[] data, Camera camera) { // 根据拍照所得的数据创建位图 final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); // 加载save.xml文件对应的布局资源 View saveDialog = getLayoutInflater().inflate(R.layout.save, null); final EditText photoName = (EditText) saveDialog .findViewById(R.id.save_et_name); ImageView showView = (ImageView) saveDialog .findViewById(R.id.save_image); // 显示刚刚拍得的照片 showView.setImageBitmap(bitmap); // 使用对话框显示saveDialog组件 new AlertDialog.Builder(TestCameraActivity.this) .setView(saveDialog) .setPositiveButton("保存", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 创建一个位于SD卡上的文件 File file = new File(Environment .getExternalStorageDirectory(), photoName.getText().toString() + ".jpg"); FileOutputStream outStream = null; try { // 打开指定文件对应的输出流 outStream = new FileOutputStream(file); // 把位图输出到指定文件中 bitmap.compress(CompressFormat.JPEG, 100, outStream); outStream.close(); } catch (Exception e) { e.printStackTrace(); } } }).setNegativeButton("取消", null).show(); // 重新预览 camera.stopPreview(); camera.startPreview(); isPreview = true; } }; }
Activity的布局XML就一个拍照按钮和SurfaceView组件,就此省略
对话框的布局XML:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="输入照片名称" /> <EditText android:id="@+id/save_et_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:singleLine="true" /> </LinearLayout> <ImageView android:id="@+id/save_image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
加上如下权限:
<!-- 写入外部存储卡的权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 加入拍照权限 --> <uses-permission android:name="android.permission.CAMERA" /> <!-- 加入摄像头的附加功能 --> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 加入闪光灯权限 --> <uses-permission android:name="android.permission.FLASHLIGHT" />
另外,拍照按钮也可以使用手机上的快捷键,回调OnKeyDown()方法既可。