Android实现摄像头拍照功能
应用场景:
在Android开发过程中,有时需要调用手机自身设备的功能,本文侧重摄像头拍照功能的调用。
知识点介绍:
使用权限:调用手机自身设备功能(摄像头拍照功能),应该确保已经在AndroidManifest.xml中正确声明了对摄像头的使用及其它相关的feature。
<!--摄像头权限 --> <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"/> <!--Camera Feature 声明对camera feature的使用 --> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" /> <!--视频、录音权限 请求音频捕获权限 --> <uses-permission android:name="android.permission.RECORD_VIDEO"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/>
Class类:
1、 SurfaceView
视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
2、 SurfaceHolder
SurfaceHolder是控制surface的一个抽象接口,你可以通过SurfaceHolder来控制surface的尺寸和格式,或者修改surface的像素,监视surface的变化等等,SurfaceHolder是SurfaceView的典型接口。
3、 SurfaceHolder.Callback
用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时, 它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。设置Callback的方法是SurfaceHolder.addCallback。
使用方式:
第一步:新建一个Android项目CameraTest,包含两个Activity: MainActivity、CameraActivity。
第二步:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:background="#FFFFFF" android:layout_height="match_parent" tools:context=".MainActivity" > <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent"> <ImageView android:id="@+id/main_image" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" android:layout_width="match_parent"/> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:orientation="horizontal"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/main_camera" android:text="拍照"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="退出" android:id="@+id/main_quit"/> </LinearLayout> </RelativeLayout>
MainActivity.java
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity { private Button cameraButton; //拍照按钮 private Button quitButton; //退出按钮 private ImageView imageView; //图片显示 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); } private void initViews() { imageView = (ImageView) findViewById(R.id.main_image); // 从本地取图片(在sdcard中获取文件) Bitmap bitmap = getLoacalBitmap("/sdcard/mhc.jpg"); Log.e("msgTag", new File("/sdcard/mhc.jpg").exists()+"=========="); imageView .setImageBitmap(bitmap); //设置Bitmap cameraButton = (Button) findViewById(R.id.main_camera); quitButton = (Button) findViewById(R.id.main_quit); MainOnClickListener mainOnClickListener = new MainOnClickListener(); cameraButton.setOnClickListener(mainOnClickListener); quitButton.setOnClickListener(mainOnClickListener); } private class MainOnClickListener implements OnClickListener{ @Override public void onClick(View v) { switch (v.getId()) { case R.id.main_camera: startActivity(new Intent(MainActivity.this, CameraActivity.class)); break; case R.id.main_quit: MainActivity.this.finish(); break; default: break; } } } /** * 根据文件路径获取所需要文件,并将该文件封装成Bitmap对象返回 * @param fileUrl * @return */ public static Bitmap getLoacalBitmap(String fileUrl) { try { FileInputStream fis = new FileInputStream(fileUrl); return BitmapFactory.decodeStream(fis); ///把流转化为Bitmap图片 } catch (FileNotFoundException e) { e.printStackTrace(); return null; } } }
activity_camera.xml
<RelativeLayout 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:background="#FFFFFF" tools:context=".CameraActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" > <SurfaceView android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_vertical|center_horizontal" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> <Button android:id="@+id/camera_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="拍照" /> </LinearLayout> </RelativeLayout>
CameraActivity.java
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import android.graphics.ImageFormat; import android.hardware.Camera; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class CameraActivity extends Activity { private String tag ="CameraActivity"; private SurfaceView surfaceView; //Surface的控制器 private SurfaceHolder surfaceHolder; private Camera camera; private Button saveButton; //拍照的回调接口 private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { new SavePictureTask().execute(data); camera.startPreview(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); initViews(); } private void initViews() { saveButton = (Button) findViewById(R.id.camera_save); surfaceView = (SurfaceView) findViewById(R.id.camera_preview); surfaceHolder = surfaceView.getHolder(); // 给SurfaceView当前的持有者 SurfaceHolder 一个回调对象。 //用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时, //它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。 //设置Callback的方法是SurfaceHolder.addCallback. //实现过程一般继承SurfaceView并实现SurfaceHolder.Callback接口 surfaceHolder.addCallback(surfaceCallback); // 设置surface不需要自己的维护缓存区 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); saveButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { camera.takePicture(null, null, pictureCallback); // Camera.takePicture(shutterCallback,rawCallback,pictureCallback ); // private ShutterCallback shutterCallback = new ShutterCallback(){ // public void onShutter(){ // /* 按快门瞬间会执行这里的代码 */ // } // }; // private PictureCallback rawCallback = new PictureCallback(){ // public void onPictureTaken(byte[] _data, Camera _camera){ // /* 如需要处理 raw 则在这里 写代码 */ // } // }; // //当拍照后 存储JPG文件到 sd卡 // PictureCallback pictureCallback=new PictureCallback(){ // public void onPictureTaken(byte[] data,Camera camera) { // FileOutputStream outSteam=null; // try{ // SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmss"); // String times=format.format((new Date())); // outSteam=new FileOutputStream("/sdcard/"+times+"mhc.jpg"); // outSteam.write(data); // outSteam.close(); // }catch(FileNotFoundException e){ // Log.d("Camera", "row"); // } catch (IOException e) { // e.printStackTrace(); // } // }; // }; } }); } //SurfaceView当前的持有者的回调接口的实现 SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { camera = Camera.open(); Log.e(tag, "摄像头Open完成"); try { camera.setPreviewDisplay(holder); } catch (IOException e) { camera.release(); camera = null; } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Camera.Parameters parameters = camera.getParameters(); parameters.setPictureFormat(ImageFormat.JPEG); camera.setDisplayOrientation(0); camera.setParameters(parameters); camera.startPreview(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { camera.stopPreview(); camera.release(); camera = null; } }; class SavePictureTask extends AsyncTask<byte[], String, String> { @Override protected String doInBackground(byte[]... params) { File picture = new File("/sdcard/mhc.jpg"); try { FileOutputStream fos = new FileOutputStream(picture.getPath()); fos.write(params[0]); fos.close(); } catch (Exception e) { e.printStackTrace(); } Log.e(tag, "照片保存完成"); CameraActivity.this.finish(); return null; } } }
下载地址:Android实现摄像头拍照功能
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Android实现EditText中添加和删除bitmap的方法
这篇文章主要介绍了Android实现EditText中添加和删除bitmap的方法,实例分析了Android中EditText控件的bitmap操作技巧,需要的朋友可以参考下2016-01-01Android开发之在程序中时时获取logcat日志信息的方法(附demo源码下载)
这篇文章主要介绍了Android开发之在程序中时时获取logcat日志信息的方法,结合实例形式较为详细的分析了实时获取logcat日志的原理、步骤与相关实现技巧,并附带相应的demo源码供读者下载参考,需要的朋友可以参考下2016-02-02Android Jetpack结构运用Compose实现微博长按点赞彩虹效果
Compose在动画方面下足了功夫,提供了丰富的API。但也正由于API种类繁多,如果想一气儿学下来,最终可能会消化不良,导致似懂非懂。结合例子学习是一个不错的方法,本文就带大家边学边做,通过实现一个微博长按点赞的动画效果,学习了解Compose动画的常见思路和开发技巧2022-07-07
最新评论