博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 学习笔记之如何实现简单相机功能
阅读量:6457 次
发布时间:2019-06-23

本文共 14871 字,大约阅读时间需要 49 分钟。

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; } }}

这样就实现了视频的录制...非常的简单.....

 

转载地址:http://pzizo.baihongyu.com/

你可能感兴趣的文章
三层架构dal 层基本代码 非查询/查询
查看>>
CSS制作三角形和按钮
查看>>
java 并发多线程显式锁概念简介 什么是显式锁 多线程下篇(一)
查看>>
Python学习心得!
查看>>
支付宝的性能测试
查看>>
iOS 网络请求 NSURLSession 的上传文件方法
查看>>
devDependencies 和 dependencise 的区别
查看>>
开源移动医疗应用框架:mHealhDroid及APP
查看>>
[设计模式]装饰模式
查看>>
Python3学习
查看>>
RAID0+1 RAID5 性能比较
查看>>
Elasticsearch基本命令
查看>>
23种设计模式介绍(一)---- 创建型模式
查看>>
JavaIO简单代码实例
查看>>
Document Library SPQuery 文档库 查询
查看>>
【开源.NET】 分享一个前后端分离的轻量级内容管理框架
查看>>
每周一荐:学习ACE一定要看的书
查看>>
c# winform 之DataGridViewComboBoxColumn的使用
查看>>
2014.5.20知识点学习:void与void*(转载)
查看>>
一步一步学习SignalR进行实时通信_2_Persistent Connections
查看>>