前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android实现摄像头拍照功能

Android实现摄像头拍照功能

作者头像
砸漏
发布2020-11-05 14:37:11
6840
发布2020-11-05 14:37:11
举报
文章被收录于专栏:恩蓝脚本恩蓝脚本恩蓝脚本

应用场景:

在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实现摄像头拍照功能

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档