安卓照相机开发

        目前的智能手机大都已支持照相机应用,在安卓开发中也经常会用到照相机这一模块,那么该如何调用这一模块呢?

    一般有两种方法,不过也是根据具体需要来定,如果只是调用照相机应用,不涉及其他操作,建议直接调用系统原生照相机,如果希望个性化定制照相机应用,则需要自己设计显示框、相机参数和功能操作等。

    1、调用系统原生照相机:

       可以在源代码中定义一个调用相机的方法,并在方法中加入如下语句:    

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
        intent.putExtra("camerasensortype", 2); // 调用前置摄像头,不同屏可能参数不同  
        intent.putExtra("autofocus", false); // 是否自动对焦  
        intent.putExtra("fullScreen", false); // 是否全屏  
        intent.putExtra("showActionIcons", false); //是否显示活动图标 
  
        startActivityForResult(intent, PICK_FROM_CAMERA);//启动照相机应用
            2、自定义照相机:

       首先要创建一个相机类:CameraDialog.java

package com.android.xxx;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;

import com.android.xxx.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
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.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.view.Display;
import android.view.KeyEvent;
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 CameraDialog extends Activity {
	SurfaceView sView;
	SurfaceHolder surfaceHolder;
	int screenWidth, screenHeight;
	// 定义系统所用的照相机
	public static Camera camera = null;
	public static CameraDialog instance = null;
	// 是否在浏览中
	boolean isPreview = false;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
				WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		// 设置全屏
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.camera_dialog1);
		instance = this;
		WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		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() {
			public void surfaceChanged(SurfaceHolder holder, int format,
					int width, int height) {
			}

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

			public void surfaceDestroyed(SurfaceHolder holder) {
				// 如果camera不为null ,释放摄像头
				if (camera != null) {
					if (isPreview)
						camera.stopPreview();
					camera.release();
					camera = null;
				}
			}
		});
		// 设置该SurfaceView自己不维护缓冲
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

		// MyTag可以随便写,可以写应用名称等
		PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
		// 换成PowerManager.SCREEN_DIM_WAKE_LOCK会变暗)
		PowerManager.WakeLock wl = pm.newWakeLock(
				PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "MyTest1");
		wl.acquire();// 开启屏幕常亮
	}

	private void initCamera() {
		if (!isPreview) {
			camera = Camera.open(0);//指定要打开的摄像头0为后置,1为前置
		}
		if (camera != null && !isPreview) {
			try {
				Camera.Parameters parameters = camera.getParameters();
				// 设置预览照片的大小
				// 设置显示图像旋转90度
				if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
					setDisplayOrientation(camera, 90);
				} else {
					if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
						parameters.set("orientation", "portrait");
						parameters.set("rotation", 90);
					}
					if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
						parameters.set("orientation", "landscape");
						parameters.set("rotation", 90);
					}
				}

				List<Size> sizes = parameters.getSupportedPreviewSizes();
				Size optimalSize = getOptimalPreviewSize(sizes, 0, 0);
				parameters.setPreviewSize(optimalSize.width, optimalSize.height);//可根据优选方法设定预览分辨率,默认全屏显示
				// parameters.setPreviewSize(screenWidth, screenHeight);//可设置指定的预览分辨率(一般只支持:176x144,320x240,352x288,480x360,640x480这几个分辨率,可根据实际情况来选)
				// 每秒显示4帧
				parameters.setPreviewFrameRate(5);
				// 设置图片格式
				parameters.setPictureFormat(PixelFormat.JPEG);
				// 设置JPG照片的质量
				parameters.set("jpeg-quality", 85);
				// 设置照片的大小
				// parameters.setPictureSize(3264, 2448);//根据相机本身支持的分辨率大小
				// parameters.setPictureSize(optimalSize.width,optimalSize.height);//如果不清楚分辨率大小,可调用优选方法自动指定一个分辨率
				// parameters.setPictureSize(screenWidth, screenHeight);
				camera.setParameters(parameters);
				// 通过SurfaceView显示取景画面
				camera.setPreviewDisplay(surfaceHolder);
				// 开始预览
				camera.startPreview();
				// 自动对焦
				camera.autoFocus(null);
			} catch (Exception e) {
				e.printStackTrace();
			}
			isPreview = true;
		}
	}

	public void setDisplayOrientation(Camera camera, int angle) {
		Method downPolymorphic;
		try {
			downPolymorphic = camera.getClass().getMethod(
					"setDisplayOrientation", new Class[] { int.class });
			if (downPolymorphic != null)
				downPolymorphic.invoke(camera, new Object[] { angle });
		} catch (Exception e1) {
		}
	}

	@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() {
		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 photoName = (EditText) saveDialog
					.findViewById(R.id.phone_name);
			// 获取saveDialog对话框上的ImageView组件
			ImageView show = (ImageView) saveDialog.findViewById(R.id.show);
			// 显示刚刚拍得的照片
			show.setImageBitmap(bm);
			// 使用对话框显示saveDialog组件
			new AlertDialog.Builder(CameraDialog1.this).setView(saveDialog)
					.setPositiveButton("保存", new OnClickListener() {
						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);
								// 把位图输出到指定文件中
								bm.compress(CompressFormat.JPEG, 100, outStream);
								outStream.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}).setNegativeButton("取消", null).show();
			// 重新浏览
			camera.stopPreview();
			camera.startPreview();
			isPreview = true;
		}
	};

	private Size getOptimalPreviewSize(List<Size> sizes, int w, int h)//分辨率尺寸优选方法 
        {
		final double ASPECT_TOLERANCE = 0.05;
		double targetRatio = (double) w / h;
		if (sizes == null)
			return null;
		Size optimalSize = null;
		double minDiff = Double.MAX_VALUE;
		int targetHeight = h;
		// Try to find an size match aspect ratio and size
		for (Size size : sizes) {
			double ratio = (double) size.width / size.height;
			if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
				continue;
			if (Math.abs(size.height - targetHeight) < minDiff) {
				optimalSize = size;
				minDiff = Math.abs(size.height - targetHeight);
			}
		}
		// Cannot find the one match the aspect ratio, ignore the requirement
		if (optimalSize == null) {
			minDiff = Double.MAX_VALUE;
			for (Size size : sizes) {
				if (Math.abs(size.height - targetHeight) < minDiff) {
					optimalSize = size;
					minDiff = Math.abs(size.height - targetHeight);
				}
			}
		}
		return optimalSize;
	}
}
        其次,在主类中创建调用方法,并在其中添加如下两句:

     Intent intent = new Intent(MainActivity.this, CameraDialog.class);
     startActivity(intent);
        在适当的时候调用该方法即可。

       最后,注意在AndroidManifest.xml中添加相关权限配置:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android:hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
        至此,自定义的照相机应用便设计出来了,它包含预览、自动对焦、拍照和照片存储功能。          




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彧侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值