Android自定义相机实现定时拍照
这篇是和大家介绍Android自定义相机,并且实现倒计时拍照功能。
首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件:
activity_main.xml
[html]viewplaincopy在CODE上查看代码片派生到我的代码片
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:src="@drawable/capture"/>
android:id="@+id/count_down"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:textSize="80sp"/>
MainActivity.Java
[java]viewplaincopy在CODE上查看代码片派生到我的代码片
packagecom.jackie.timercamera;
importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Matrix;
importandroid.hardware.Camera;
importandroid.media.AudioManager;
importandroid.media.MediaPlayer;
importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.os.Handler;
importandroid.support.v7.app.AppCompatActivity;
importandroid.util.Log;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
importandroid.view.View;
importandroid.widget.ImageView;
importandroid.widget.TextView;
importjava.io.File;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
publicclassMainActivityextendsAppCompatActivityimplementsSurfaceHolder.Callback,
View.OnClickListener,Camera.PictureCallback{
privateSurfaceViewmSurfaceView;
privateImageViewmIvStart;
privateTextViewmTvCountDown;
privateSurfaceHoldermHolder;
privateCameramCamera;
privateHandlermHandler=newHandler();
privateintmCurrentTimer=10;
privatebooleanmIsSurfaceCreated=false;
privatebooleanmIsTimerRunning=false;
privatestaticfinalintCAMERA_ID=0;//后置摄像头
//privatestaticfinalintCAMERA_ID=1;//前置摄像头
privatestaticfinalStringTAG=MainActivity.class.getSimpleName();
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}
@Override
protectedvoidonPause(){
super.onPause();
stopPreview();
}
privatevoidinitView(){
mSurfaceView=(SurfaceView)findViewById(R.id.surface_view);
mIvStart=(ImageView)findViewById(R.id.start);
mTvCountDown=(TextView)findViewById(R.id.count_down);
}
privatevoidinitEvent(){
mHolder=mSurfaceView.getHolder();
mHolder.addCallback(this);
mIvStart.setOnClickListener(this);
}
@Override
publicvoidsurfaceCreated(SurfaceHolderholder){
mIsSurfaceCreated=true;
}
@Override
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight){
startPreview();
}
@Override
publicvoidsurfaceDestroyed(SurfaceHolderholder){
mIsSurfaceCreated=false;
}
privatevoidstartPreview(){
if(mCamera!=null||!mIsSurfaceCreated){
Log.d(TAG,"startPreviewwillreturn");
return;
}
mCamera=Camera.open(CAMERA_ID);
Camera.Parametersparameters=mCamera.getParameters();
intwidth=getResources().getDisplayMetrics().widthPixels;
intheight=getResources().getDisplayMetrics().heightPixels;
Camera.Sizesize=getBestPreviewSize(width,height,parameters);
if(size!=null){
//设置预览分辨率
parameters.setPreviewSize(size.width,size.height);
//设置保存图片的大小
parameters.setPictureSize(size.width,size.height);
}
//自动对焦
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
parameters.setPreviewFrameRate(20);
//设置相机预览方向
mCamera.setDisplayOrientation(90);
mCamera.setParameters(parameters);
try{
mCamera.setPreviewDisplay(mHolder);
}catch(Exceptione){
Log.d(TAG,e.getMessage());
}
mCamera.startPreview();
}
privatevoidstopPreview(){
//释放Camera对象
if(mCamera!=null){
try{
mCamera.setPreviewDisplay(null);
mCamera.stwww.baiyuewang.netopPreview();
mCamera.release();
mCamera=null;
}catch(Exceptione){
Log.e(TAG,e.getMessage());
}
}
}
privateCamera.SizegetBestPreviewSize(intwidth,intheight,
Camera.Parametersparameters){
Camera.Sizeresult=null;
for(Camera.Sizesize:parameters.getSupportedPreviewSizes()){
if(size.width<=width&&size.height<=height){
if(result==null){
result=size;
}else{
intresultArea=result.widthresult.height;
intnewArea=size.widthsize.height;
if(newArea>resultArea){
result=size;
}
}
}
}
returnresult;
}
@Override
publicvoidonClick(Viewv){
switch(v.getId()){
caseR.id.start:
if(!mIsTimerRunning){
mIsTimerRunning=true;
mHandler.post(timerRunnable);
}
break;
}
}
privateRunnabletimerRunnable=newRunnable(){
@Override
publicvoidrun(){
if(mCurrentTimer>0){
mTvCountDown.setText(mCurrentTimer+"");
mCurrentTimer--;
mHandler.postDelayed(timerRunnable,1000);
}else{
mTvCountDown.setText("");
mCamera.takePicture(null,null,null,MainActivity.this);
playSound();
mIsTimerRunning=false;
mCurrentTimer=10;
}
}
};
@Override
publicvoidonPictureTaken(byte[]data,Cameracamera){
try{
FileOutputStreamfos=newFileOutputStream(newFile
(Environment.getExternalStorageDirectory()+File.separator+
System.currentTiwww.tt951.commeMillis()+".png"));
//旋转角度,保证保存的图片方向是对的
Bitmapbitmap=BitmapFactory.decodeByteArray(data,0,data.length);
Matrixmatrix=newMatrix();
matrix.setRotate(90);
bitmap=Bitmap.createBitmap(bitmap,0,0,
bitmap.getWidth(),bitmap.getHeight(),matrix,true);
bitmap.compress(Bitmap.CompressFormat.PNG,100,fos);
fos.flush();
fos.close();
}catch(FileNotFoundExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
mCamera.startPreview();
}
/
播放系统拍照声音
/
publicvoidplaySound(){
MediaPlayermediaPlayer=null;
AudioManageraudioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
intvolume=audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
if(volume!=0){
if(mediaPlayer==null)
mediaPlayer=MediaPlayer.create(this,
Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));
if(mediaPlayer!=null){
mediaPlayer.start();
}
}
}
}
有两点需要注意:对于Camera来说,默认是横屏的,所以预览的时候和图片保存的时候都是横屏的,需要调整角度。
设置相机预览方法:
//设置相机预览方向
mCamera.setDisplayOrientation(90);
|
|