自定义Camera

Posted 0 and 1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义Camera相关的知识,希望对你有一定的参考价值。

今天来学习自定义Camera

实现相机拍照功能

拍照界面:

因为取景框要有实时刷新的效果所以普通的view不行,一般使用surfaceView

上面的按钮是拍照按钮

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.cameratest1.MyCamera" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="capture"
        android:text="Capture" />

    <SurfaceView
        android:id="@+id/preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

然后写一个Activity实现拍照的逻辑控制,MyCamera,

实现几个方法

拍照按钮点击事件

public void capture(View view){}

 获取Camera对象方法

private Camera getCamera(){}

开始预览相机内容方法,将Camera与SurfaceView进行绑定,
使Camera的实时预览效果显示在SurfaceView
 中

private void setStartPreview(Camera camera,SurfaceHolder holder){}

* 释放系统相机资源
private void releaseCamera(){}

全部代码

public class MyCamera extends Activity implements SurfaceHolder.Callback{

	private Camera mCamera;
	private SurfaceView mPreview;

	private SurfaceHolder mHolder;
	private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {

		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			// TODO Auto-generated method stub
			//这里的data是真实图片数据不是缩略图
			File tempFile = new File("/sdcard/tddemp.png");
			try {
				FileOutputStream fos = new FileOutputStream(tempFile);
				fos.write(data);//将拍到的数据写入文件
				fos.close();
				//将拍到的数据传递到resultActivity中显示出来
				Intent intent = new Intent(MyCamera.this, ResultActivity.class);
				intent.putExtra("picPath", tempFile.getAbsolutePath());
				startActivity(intent);
				MyCamera.this.finish();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_my_camera);
		mPreview = (SurfaceView) findViewById(R.id.preview);
		mHolder = mPreview.getHolder();
		mHolder.addCallback(this);
	}
	public void	capture(View view){
		//设置拍照参数
		Camera.Parameters parameters = mCamera.getParameters();
		parameters.setPictureFormat(ImageFormat.JPEG);//设置拍照格式
		parameters.setPictureSize(800, 400);//设置拍照大小
		parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);//设置自动对焦
		//获取最清晰的焦距
		mCamera.autoFocus(new Camera.AutoFocusCallback() {

			@Override
			public void onAutoFocus(boolean success, Camera camera) {
				// TODO Auto-generated method stub
				if (success) {
					mCamera.takePicture(null, null, mPictureCallback);
					//第三个参数是回调方法
				}

			}
		});

	}

	/**
	 * 使用系统相机需要以下方法
	 */
	/**
	 * 获取Camera对象
	 * @return
	 */
	private Camera getCamera(){
		//这里使用导入的是硬件的Camera,import android.hardware.Camera;
		Camera camera;
		camera = Camera.open();
		return camera;
	}
	/**
	 * 开始预览相机内容,将Camera与SurfaceView进行绑定,
	 * 使Camera的实时预览效果显示在SurfaceView
	 * 中
	 */
	private void setStartPreview(Camera camera,SurfaceHolder holder){
		try {
			camera.setPreviewDisplay(holder);
			camera.startPreview();
			camera.setDisplayOrientation(90);//系统默认显示横屏的Camera,旋转为竖屏
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 释放系统相机资源
	 */
	private void releaseCamera(){

		if (mCamera!=null) {
			mCamera.setPreviewCallback(null);//去掉回调,取消与SuferView的关联
			mCamera.stopPreview();//停止取景
			mCamera.release();
			mCamera =null;
		}

	}
	/**
	 * 将Camera的生命周期与Activity的生命周期进行绑定
	 */
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		if (mCamera == null) {
			mCamera = getCamera();
			if(mHolder != null){
				setStartPreview(mCamera, mHolder);
			}
		}
	}
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		releaseCamera();

	}
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		//重启
		mCamera.stopPreview();
		setStartPreview(mCamera, mHolder);
	}
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		setStartPreview(mCamera, mHolder);
	}
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		releaseCamera();
	}
}

写一个ResultActivity,这样在拍照界面点击拍照按钮后,将图片在ResultActivtiy中获取显示


public class ResultActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_result);
		String path = getIntent().getStringExtra("picPath");

		ImageView imageView = (ImageView) findViewById(R.id.pic);

		try {
			FileInputStream fis = new FileInputStream(path);
			Bitmap bitmap = BitmapFactory.decodeStream(fis);
			/**
			 * 让图像显示为竖屏,拍照时默认系统取景为横屏,存储的也是横屏的数据,这里需要做如下处理
			 */
			Matrix matrix = new Matrix();//矩阵
			matrix.setRotate(90);//通过变换矩阵旋转角度
			bitmap = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix, true);
			imageView.setImageBitmap(bitmap);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//		Bitmap bitmap = BitmapFactory.decodeFile(path);
		//		imageView.setImageBitmap(bitmap);

	}
}

ResultActivity界面布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.cameratest1.ResultActivity" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Capture result"
        android:textSize="20sp" />

    <ImageView
        android:id="@+id/pic"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="center" />

</LinearLayout>
在MainActivity中点击拍照按钮进行拍照:

public void openmyCamera(View view){
		//打开自定义的相机
		startActivity(new Intent(this,MyCamera.class));
	}
然后进入MyCamera界面进行拍照取景,点击确定后将拍到的图片在ResultActivity中显示

一共涉及3个Activity

以上是关于自定义Camera的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段(vue主模板)

VSCode自定义代码片段——声明函数

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段——git命令操作一个完整流程

VSCode自定义代码片段8——声明函数