PS:看来算法和数据结构还是非常有用的,以后每天都练习两道算法题目...这次忘了对代码进行折叠了..导致篇幅过长...
学习内容:
1.Android如何实现相机功能...
2.如何实现音频的录制...
3.如何实现视频的录制...
Android的相机是Android手机内部必不可少的一个应用软件...那么Android的相机机制是如何实现的呢?在Android内部提供了一个内部类android.view.SurfaceHolder这个类,这个类提供了SurfaceView,这个类可以帮助我们实现照相功能...SurfaceView想必都很熟悉了...使用它我们还可以进行视频音频的播放...在这个类的基础上,我们还可以通过Camera类提供的内部方法,对相机的参数进行一些相应的设置,以达到我们拍照时想要的效果...Camera内部还定义了若干个接口来完成一些相应的操作...比如说按下快门的时候要处理什么样的操作...
通过Camera来操控摄像头需要按照步骤来...
i.首先调用Camera的open方法来打开摄像头...
//现在的相机一般都有两个摄像头,我们需要定义我们想要打开哪个摄像头,默认的是后置的摄像头...这里打开的也是后置的摄像头...if(Camera.getNumberOfCameras()==2){ camera=Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); }else{ camera=Camera.open(0); }
ii.接着调用getParammeters来获取相机的参数...
Parameters param=MainActivity.this.camera.getParameters();//获取相机参数的方法...
iii.设置相机的相应参数,来达到我们想要的效果...
param.setPreviewFrameRate(5);//设置预览时每秒五帧进行显示 param.setPictureFormat(PixelFormat.JPEG);//设置图片的格式为JPEG param.set("jpeg-quality", 80);//设置图片的质量为80,最大值为100
iv.调用setParammeters来讲我们设置的参数传递到相机,达到我们拍照时想要出现的效果...
camera.setParameters(param);
v.在我们进行拍照的时候我们必然需要先进行预览全景,在预览的某一时刻进行拍照...那么这个预览必然就需要一个SurfaceView来帮助我们来显示当前我们预览的场景...
try { MainActivity.this.camera.setPreviewDisplay(MainActivity.this.sufh);//设置预览的对象为SurfaceHolder。。。 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } MainActivity.this.camera.startPreview();//开始预览..
vi.开始拍照...获取图片,然后对图片进行保存,最后释放内存...总体也就分这么几个步骤...
然后我们首先一个简单的拍照功能...
简单说一下java文件里如何实现拍照的一个思路,首先我们必然需要打开一个摄像头,然后接着我们需要获取摄像头的参数,然后自定义我们拍照时想要的一些设置,这些设置呢那么必然需要先传递到摄像头,否则不进行传递的话,摄像头也就不会按照我们设置的参数进行工作,因此我们需要传递参数,传递完参数后,我们就需要进行拍照了,在拍照的时候呢,我们需要预览景观,那么预览的功能就需要使用到SurfaceView这个类定义一个表面的视图控件,说白了就是需要一块面积来显示现在用户想看到的东西,然后在预览的时候我们就可以进行拍照了,拍照需要使用takepicture()这个方法来完成,然后获取到图片,最后我们把照片数据通过IO流来写入到内存当中,最后进行保存...这就是实现代码...
package com.example.camera;/* * 1.首先调用Camera的open()方法打开摄像机... * private Camera camera; * camera=Camera.open(0); * 2.调用Camera.setParameters()方法获取摄像机的参数... * Parameters param=camera.setParameters(); * 3.设置摄像机的拍照参数来配置拍照信息... * param.setPreviewSize(display.getWidth(),display.getHeight());设置预览大小.. * param.setPreviewFrameRate(4)..以每秒四帧显示图像信息... * param.setPictureFormat(PixelFormat.JPEG);设置图片的格式... * param.set("jpeg-quality",85);设置图片的质量,最高为100... * parameters.setPictureSize(screenWidth,screenHeight);设置照片的大小... * 4.param.setParamters(param);将参数传递给相机,使相机可以指定相应的参数来完成拍摄... * 5.使用setPreview(SurfaceView)设置使用哪个SurfaceView来显示要预览的景象... * MainActivity.this.cma.setPreView(SurfaceHolder holder)...防止主线程阻塞..因此另外开启线程... * MainActivity.this.cma.startPreView();开始预览... * MainActivity.this.cma.autoFocus(afcb); * 6.进行拍照,然后获取拍到的图片进行保存... * cma.takePicture(sc,pc,jpgcall);获取图片... * 7.结束预览释放资源... * cma.stopPreView(); * cma.release();释放资源.. * 8.在AndroidManifest设置权限... ** * * * * */import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;import android.os.Bundle;import android.os.Environment;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.view.Display;import android.view.Menu;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.view.WindowManager;import android.widget.Toast;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Picture;import android.graphics.PixelFormat;import android.hardware.Camera;import android.hardware.Camera.AutoFocusCallback;import android.hardware.Camera.Parameters;import android.hardware.Camera.PictureCallback;import android.hardware.Camera.ShutterCallback;import android.hardware.Camera.Size;public class MainActivity extends Activity implements View.OnClickListener { private boolean previewrunning=true; private Camera camera=null; private SurfaceView suf; private SurfaceHolder sufh; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏显示... super.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//高亮显示... setContentView(R.layout.activity_main); suf=(SurfaceView) findViewById(R.id.surface); sufh=suf.getHolder();//获取SurfaceHolder... sufh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置一个缓冲区...就是一个缓冲的Surface...这个Surface的数据来源于Camera.. sufh.setFixedSize(480, 800);//设置分辨率为480*800 findViewById(R.id.but).setOnClickListener(this); sufh.addCallback(new SurfaceHolder.Callback() { //这里就很清晰了,在使用到了SurfaceView时必然要获取SurfaceHolder接口,然后进行回调.. @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub if(MainActivity.this.camera!=null){ if(MainActivity.this.previewrunning){ MainActivity.this.camera.stopPreview(); MainActivity.this.previewrunning=false; } MainActivity.this.camera.release(); } } @SuppressLint("NewApi") @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub if(Camera.getNumberOfCameras()==2){ //获取相机... camera=Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); }else{ camera=Camera.open(0); } camera.setDisplayOrientation(90);//这个就是设置屏幕需要旋转90度,一般没这句话屏幕内的东西都是纵向的... WindowManager manager=(WindowManager) MainActivity.this.getSystemService(Context.WINDOW_SERVICE);//获取窗口服务.. Display display=manager.getDefaultDisplay();//获取display对象.. Parameters param=MainActivity.this.camera.getParameters();//获取参数 param.setPreviewSize(display.getWidth(), display.getHeight());//设置预览时图片的大小.. param.setPictureSize(display.getWidth(), display.getHeight());//设置拍照后图片的大小.. param.setPreviewFrameRate(5);//设置预览的时候以每秒五帧进行显示... param.setPictureFormat(PixelFormat.JPEG);//设置图片的格式为JPEG... param.set("jpeg-quality", 80);//设置图片的质量... // List listsize=param.getSupportedPreviewSizes();// System.out.println(listsize.size());// if(null!=listsize && 0 map=new HashMap ();// for(int i=0;i
最后我们需要获取一些权限,需要在AndroidManifest.xml文件内部进行权限设置...
这样通过以上的方式,就实现了简单照相机的拍照功能...
2.Android如何实现音频与视频的录制...
Android的实现音频和视频的录制是非常的简单的...只需要几个步骤就可以完成了...这里我们需要使用到android.media.MediaRecorder这个类,同过实例化对象,我们就可以对视频和音频进行录制了...通过内部提供的一些方法,我们就可以自定义一些属性...
1.首先初始化对象...MediaRecorder re=new MediaRecorder();2.设置视频和音频的文件来源...re.setAudioSource(MediaRecorder.AudioSource.MIC);3.设置输出的文本格式...re.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);4.设置音频的编码..AudioEncoder.DEFAULT和AudioEncoder.AMR_NB两种格式...re.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);5.设置文件的存储路径...re.setOutputFile(PATH_NAME);6.准备录制...re.prepare();7.开始录制...re.start();8.在AndroidManifest.xml文件中进行相应的配置...这就是实现音频录制的过程....来一个简单的实现代码...
配置xml的权限设置...
最后就是java内部如何进行实现...
package com.example.recoder;/* 如何实现视频和音频的录制 * 音频 * 1.首先初始化对象...MediaRecorder re=new MediaRecorder(); * 2.设置视频和音频的文件来源...re.setAudioSource(MediaRecorder.AudioSource.MIC); * 3.设置输出的文本格式...re.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); * 4.设置音频的编码..AudioEncoder.DEFAULT和AudioEncoder.AMR_NB两种格式...re.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); * 5.设置文件的存储路径...re.setOutputFile(PATH_NAME); * 6.准备录制...re.prepare(); * 7.开始录制...re.start(); * 8.在AndroidManifest.xml文件中进行相应的配置.. * * */import java.io.File;import java.io.IOException;import android.os.Bundle;import android.os.Environment;import android.app.Activity;import android.view.Menu;import android.view.View;import android.widget.TextView;import android.widget.Toast;import android.media.MediaRecorder;public class MainActivity extends Activity implements View.OnClickListener { private TextView tv; private MediaRecorder mr; private File soundFile; private File MediaFile; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv=(TextView) findViewById(R.id.msg); findViewById(R.id.start).setOnClickListener(this); findViewById(R.id.stop).setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()){ case R.id.start:{ tv.setText("---开始录音---"); //判断sd卡的状态信息.. if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //sd卡没有正常挂载... Toast.makeText(MainActivity.this, "请插入sd卡", Toast.LENGTH_LONG).show();//在屏幕上显示信息... return; } mr=new MediaRecorder(); //获取sd卡的根目录... MediaFile=Environment.getExternalStorageDirectory(); try { soundFile=File.createTempFile("exam_Recorder", ".arm", MediaFile);//新建一个文件,前两个参数为前缀名和后缀名,这里自己定义,第三个参表示的是文件的目录... mr.setAudioSource(MediaRecorder.AudioSource.MIC);//设置录制的音频来源为手机麦克风 mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置输出格式,就是以什么格式进行保存... mr.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);//设置音频的编码为什么形式... mr.setOutputFile(soundFile.getAbsolutePath());//设置录音的输出文件路径...保存的位置... mr.prepare(); mr.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; } case R.id.stop:{ tv.setText("---停止录音---"); if(soundFile!=null){ mr.stop(); mr.release(); mr=null; } } default: break; } } @Override public void onDestroy(){ if(soundFile!=null&&soundFile.exists()&&mr!=null){ mr.stop(); mr.release(); mr=null; } super.onDestroy(); }}
3.视频的录制...
视频的录制,那么必然就涉及到摄像头了,想到摄像头,必然我们要使用SurfaceView类了...这是必然的,因为我们需要预览...录制视频的过程就是属于一直对画面进行预览,然后一帧一帧的进行记录...
同样我们需要在xml文件中配置相应的权限...设置好了权限,我们才可以进行相应的操作...
然后在java文件中进行实现...
package com.example.video;import java.io.File;import java.io.IOException;import android.media.MediaRecorder;import android.os.Bundle;import android.os.Environment;import android.app.Activity;import android.view.Menu;import android.view.SurfaceView;import android.view.SurfaceHolder;import android.view.View;import android.widget.TextView;public class MainActivity extends Activity implements View.OnClickListener { private TextView tv; private File myvideofile; private File dir; private MediaRecorder recorder; private SurfaceView suf; private SurfaceHolder holder; @SuppressWarnings("deprecation") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.start).setOnClickListener(this); findViewById(R.id.stop).setOnClickListener(this); tv=(TextView) findViewById(R.id.msg); suf=(SurfaceView) findViewById(R.id.videoView);//获取SurfaceView... holder=suf.getHolder();//获取SurfaceHolder接口... holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置一个缓冲... recorder=new MediaRecorder();//定义一个MediaRecorder对象... File Dir=Environment.getExternalStorageDirectory();//获取sd卡的根目录... String path=Dir.getAbsolutePath()+File.separator+"MyVideo"+File.separator;//设置文件路径...这里的File.separator表示的是文件之间的分隔符..Windows下为'\'... dir=new File(path); if(!dir.exists()){ //父文件夹不存在则进行新建... dir.mkdir(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.start: tv.setText("开始录制"); try { myvideofile=File.createTempFile("video", ".3gp", dir); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } recorder.setPreviewDisplay(holder.getSurface());//预览时的SrufaceView recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);//设置视频的来源...来源于相机的拍摄 recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//音频的来源于手机的麦克... recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//输出的格式... recorder.setVideoSize(800, 480);//设置预览时的分辨率.... recorder.setVideoFrameRate(15);//每秒的帧数... recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置音频的编码... recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);//设置视频的编码... recorder.setMaxDuration(1000);//设置最大的期限... recorder.setOutputFile(myvideofile.getAbsolutePath());//获取文件的输出路径...进行保存... try { recorder.prepare(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } recorder.start(); break; case R.id.stop: tv.setText("停止录制"); recorder.stop(); recorder.reset(); recorder.release(); recorder=null; } }}
这样就实现了视频的录制...非常的简单.....