Android 相机,视频录制

源自:http://my.oschina.net/kooeasy/blog/478181

现在的收集一般都会提供相机功能,有些相机大镜头已经支持1000万以上的像素,有些还支持光学变焦,这些收集已经变成了抓也数码相机,为了充分利用手机上的相机功能,Android应用可以控制拍照和录制视频。

权限相关

1
2
3
4
5
6
7
8
     <!--摄像头相关-->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--音视频相关-->
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

拍照

一、通过系统Intent进行拍照

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

创建Uri方法一:
//添加参数
ContentValues values = new ContentValues();
//设置文件名称
values.put(MediaStore.Images.Media.DISPLAY_NAME, String.valueOf(System.currentTimeMillis())+".jpg");
//设置文件类型
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
//添加存储的位置的uri
uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

创建Uri方法二:
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+System.currentTimeMillis()+".jpg");
uri = Uri.fromFile(file);

//添加图像方向
intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
//设置图像输出位置
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

startActivityForResult(intent,1);

    获取返回的图像路径

public static String getPathFromUri(Context mContext,Uri contentUri){
   String[] proj = { MediaStore.Images.Media.DATA };
   CursorLoader loader = new CursorLoader(mContext, contentUri, proj, null, null, null);
   Cursor cursor = loader.loadInBackground();
   int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
   cursor.moveToFirst();
   return cursor.getString(column_index);
}

    通过路径加载Bitmap

Bitmap bitmap = BitmapFactory.decodeFile(getPathFromUri(this, uri));

二、利用Camrea拍照

1、调用Camera的open()打开相机

2、调用Camera的getParameters()获取拍照参数。该方法返回一个Camera.Paremeters对象

3、调用Camera.Parameters对象方法设置拍照的参数

4、调用Camera.startPreview()方法开始预览取景,在预览取景之前需要调用Camera的setPreviewDisplay(SurfaceHolder holder)方法设置使用哪个SurfaceView来显示取景图片。

5、调用Camera的takePicture()方法进行拍照

6、结束程序时,调用Camera的stopPreview()结束取景预览,并调用release()方法释放资源

    

public class CameraActivity extends Activity {

   private SurfaceView mSurfaceView;
   private View mTake,mCancle;
   private SurfaceHolder mSurfaceHolder;
   private boolean isPreview = false;
   private Camera mCamera;
   private Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
       @Override
       public void onAutoFocus(boolean success, Camera camera) {
           if(success){
               // 第一个监听器;当用户按下快门时激发该监听器
               // 第二个监听器;当相机获取原始照片时激发该监听器
               // 第三个监听器;当相机获取JPG照片时激发该监听器
               mCamera.takePicture(new Camera.ShutterCallback() {
                   @Override
                   public void onShutter() {
                   //快门按下时
                   }
               }, new Camera.PictureCallback() {
                   @Override
                   public void onPictureTaken(byte[] data, Camera camera) {
                   //此处代码可以决定是否需要保存原始照片信息
                   }
               }, new Camera.PictureCallback() {
                   @Override
                   public void onPictureTaken(byte[] data, Camera camera) {
                       Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                       //创建矩阵 旋转图像
                       Matrix matrix = new Matrix();
                       matrix.setRotate(90f,bitmap.getWidth()/2,bitmap.getHeight()/2);
                       Bitmap bit =Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
                       //销毁原图
                       bitmap.recycle();

                       mImage.setImageBitmap(bit);
                       File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
                       FileOutputStream fos = null;
                       try {
                           fos = new FileOutputStream(file);
                           bit.compress(Bitmap.CompressFormat.JPEG,100,fos);
                           try {

                               fos.close();
                           } catch (IOException e) {
                               e.printStackTrace();
                           }
                       } catch (FileNotFoundException e) {
                           e.printStackTrace();
                       }
                       mCamera.stopPreview();;
                       mCamera.startPreview();
                       isPreview=true;
                   }
               });
           }
       }
   };
   private ImageView mImage;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_camera);
       initView();
       process();
       setAllClick();

   }

   private void setAllClick() {
       mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {

           @Override
           public void surfaceCreated(SurfaceHolder holder) {
               initCamera();
           }
           @Override
           public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

           }
           @Override
           public void surfaceDestroyed(SurfaceHolder holder) {
               if (mCamera != null) {
                   if (isPreview) {
                       mCamera.stopPreview();
                       mCamera.release();
                       mCamera = null;
                   }
               }
           }
       });

       mTake.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               //拍照
               if (mCamera != null) {
                   //添加自动聚焦
                   mCamera.autoFocus(autoFocusCallback);
//                    takePhoto();
               }
           }
       });
   }


   private int mPreviewWidth=0;
   private int mPreviewHeight=0;

   /**
    * 初始化相机
    */
   private void initCamera() {

       if(!isPreview){
           //打开相机
//            mCamera = Camera.open(Camera.getNumberOfCameras()-1);
           mCamera = Camera.open(0);

       }
       if(mCamera!=null&&!isPreview){
           //获取相关设置
           Camera.Parameters parameters = mCamera.getParameters();

           List<Camera.Size> previewsizes = parameters.getSupportedPreviewSizes();

           Iterator<Camera.Size> iterator = previewsizes.iterator();
           while(iterator.hasNext()){
               Camera.Size next = iterator.next();
               if(next.width>mPreviewWidth&&next.height>mPreviewHeight){
                   mPreviewWidth=next.width;
                   mPreviewHeight=next.height;
               }
               Log.i("TAG","camera->"+mPreviewWidth+":"+mPreviewHeight);
           }

           Log.i("TAG","surface->"+mSurfaceView.getWidth()+":"+mSurfaceView.getHeight());

           //设置预览招聘时每秒显示多少帧的最小值和最大值
//            parameters.setPreviewFpsRange(10, 20);
           //设置图片格式
           parameters.setPictureFormat(PixelFormat.JPEG);
           //设置预览大小
//            parameters.setPreviewSize(mPreviewWidth, mPreviewHeight);
           //设置照片大小
           parameters.setPictureSize(mPreviewWidth, mPreviewHeight);
           //设置JPG照片的质量
           parameters.set("jpeg-quality", 100);

           //设置取景的SutfaceView
           try {
               //设置显示方向
               mCamera.setDisplayOrientation(90);
               mCamera.setParameters(parameters);
               //设置配置
               mCamera.setPreviewDisplay(mSurfaceHolder);
               mCamera.startPreview();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       isPreview=true;
   }



   /**
    * 业务过程
    */
   private void process() {

       mSurfaceHolder = mSurfaceView.getHolder();
       //设置Surface不需要自己维护还冲区
       mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
   }

   /**
    * 初始化视图
    */
   private void initView() {
       mSurfaceView =(SurfaceView) findViewById(R.id.camera_view);
       mTake = findViewById(R.id.take_photo);
       mCancle = findViewById(R.id.cancle);
       mImage = (ImageView)findViewById(R.id.image);
   }

}

 

录像

一、使用系统Intent

Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
//限制时长 s
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5);
//限制大小
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024*1024);
//设置质量
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
//设置输出位置
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, 1);

    返回

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

   super.onActivityResult(requestCode, resultCode, data);
   if(resultCode==RESULT_OK){
       Uri uri = data.getData();
       //视频地址
       String videoPath = getPathFromUri(this,uri);
   }
}

    

public static String getPathFromUri(Context mContext,Uri contentUri){
   String[] proj = { MediaStore.Images.Media.DATA };
   CursorLoader loader = new CursorLoader(mContext, contentUri, proj, null, null, null);
   Cursor cursor = loader.loadInBackground();
   int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
   cursor.moveToFirst();
   return cursor.getString(column_index);
}

二、使用MediaRecord

public class RecordeActivity extends Activity {

   private SurfaceView mRecordView;
   private View mStart, mStop;
   private boolean isRecord = false;
   private SurfaceHolder mSurfaceHolder;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_recorde);

       initView();

       process();

       setAllClick();
   }

   private void setAllClick() {
       mStart.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               if(!isRecord){
                   startRecord();
               }
           }
       });
       mStop.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               if(isRecord){
                   //停止录制
                   mRecorder.stop();
                   //释放资源
                   mRecorder.release();
                   mRecorder=null;
               }
           }
       });
   }


   private File file;
   private MediaRecorder mRecorder;

   /**
    * 开始录制
    */
   private void startRecord() {
       file = new File(Environment.getExternalStorageDirectory() + "/" + System.currentTimeMillis() + ".mp4");
       try {
           //创建MediaPay对象
           mRecorder = new MediaRecorder();
           mRecorder.reset();
           //设置从麦克风采集声音
           mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
           //设置从摄像头采集图像
           mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
           mRecorder.setOrientationHint(90);
           //设置视频文件输出格式,这个设置必须在声音编码格式,图像编码格式之前设置
           mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
           //设置声音编码格式、图像编码格式
           mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
           mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
           //设置视频大小
           mRecorder.setVideoSize(1280, 960);
           //设置帧率  每秒32帧
           mRecorder.setVideoFrameRate(32);
           //设置编码比特率
           mRecorder.setVideoEncodingBitRate(5*1024*1024);
           mRecorder.setOutputFile(file.getAbsolutePath());
           //指定使用Surface来预览视频
           mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
           //准备
           mRecorder.prepare();
           //开始录制
           mRecorder.start();
           isRecord = true;
       } catch (IOException e) {
           e.printStackTrace();
       }

   }

   private void process() {
       mSurfaceHolder = mRecordView.getHolder();
       mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
       mSurfaceHolder.setKeepScreenOn(true);
   }

   private void initView() {
       mRecordView = (SurfaceView) findViewById(R.id.video_recorde);
       mStart = findViewById(R.id.start);
       mStop = findViewById(R.id.stop);
   }
}
原文地址:https://www.cnblogs.com/zhang--xiang/p/4795867.html