Android Camera

来源:互联网 发布:智业软件 编辑:程序博客网 时间:2024/06/10 03:39
Android Camera 使用小结
Android手机关于Camera的使用,一是拍照,二是摄像,由于Android提供了强大的组件功能,为此对于在Android手机系统上进行Camera的开发,我们可以使用两类方法:一是借助Intent和MediaStroe调用系统Camera App程序来实现拍照和摄像功能,二是根据Camera API自写Camera程序。由于自写Camera需要对Camera API了解很充分,而且对于通用的拍照和摄像应用只需要借助系统Camera App程序就能满足要求了,为此先从调用系统Camera App应用开始来对Android Camera做个简单的使用小结。
调用系统Camera App实现拍照和摄像功能
不是专门的Camera应用,一般用到Camera的需求就是获取照片或者视频,比如微博分享、随手记等,对于在Symbian系统上通过简单地调用系统自带的Camera APP来实现该功能是做不到的,但是Android系统强大的组件特性,使得应用开发者只需通过Intent就可以方便的打开系统自带的Camera APP,并通过MediaStroe方便地获取照片和视频的文件路径。具体我们还是用代码来说话吧:
例1、 实现拍照
在菜单或按钮的选择操作中调用如下代码,开启系统自带Camera APP,并传递一个拍照存储的路径给系统应用程序,具体如下:
imgPath = "/sdcard/test/img.jpg";
//必须确保文件夹路径存在,否则拍照后无法完成回调
File vFile = new File(imgPath);
if(!vFile.exists())
{
File vDirPath = vFile.getParentFile(); //new File(vFile.getParent());
vDirPath.mkdirs();
}
Uri uri = Uri.fromFile(vFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);//
startActivityForResult(intent, SystemCapture);
上面我们使用的是startActivityForResult,所以最好需要重载void onActivityResult(int requestCode, int resultCode, Intent data)函数,不过因为当传入文件路径的的情况下,data返回参数是null值,只要resultCode为RESULT_OK,则上述代码中/sdcard/test/img.jpg的图片文件就是最新的照片文件。所以我们在这里只需给出如下简单的代码,将其显示到ImageView中
if (resultCode == RESULT_OK)
{
iViewPic.setImageURI(Uri.fromFile(new File(imgPath)));
}
假设不传参数MediaStore.EXTRA_OUTPUT的情况下,onActivityResult函数在resultCode为RESULT_OK的情况下,data返回的参数是经过实际拍摄照片经过缩放的图像数据,可以通过类似如下方法来打印缩放图像的尺寸
if (resultCode == RESULT_OK)
{
Bitmap bmp = (Bitmap)data.getExtras().get("data");
Log.d("Test", "bmp width:" + bmp.getWidth() + ", height:" + bmp.getHeight());
}
另外假如仅仅是调用系统照相机拍照,不关心拍照结果,则可以简单使用如下代码
Intent intent = new Intent(); //调用照相机
intent.setAction("android.media.action.STILL_IMAGE_CAMERA");
startActivity(intent);
备注:上面设置MediaStore.EXTRA_OUTPUT的方法,经过手机实测除了我们设定的路径下有照片外,在手机存储卡上也会保存一份照片,默认目录为sdcard/dcim/camera下面,我曾经尝试着想如果每次返回可以取得sdcard/dcim/camera下面的路径就好了,但是目前看来没办法直接获得,可以借助MediaStroe每次去查询最后一条照片记录,应该也是可行的。
例2、 实现摄像
在摄像功能时,尝试着设置MediaStore.EXTRA_OUTPUT以传入类似拍照时的文件路径,结果在我的测试真机上,那个视频文件居然是一个0k的空文件,最后通过类似如下代码实现
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);//参数设置可以省略
startActivityForResult(intent, SystemVideoRecord);
在onActivityResult函数中进行如下代码调用
Uri videoUri = data.getData();
//String[] projection = { MediaStore.Video.Media.DATA, MediaStore.Video.Media.SIZE };
Cursor cursor = managedQuery(videoUri, null, null, null, null);
cursor.moveToFirst();//这个必须加,否则下面读取会报错
int num = cursor.getCount();
String recordedVideoFilePath = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));
int recordedVideoFileSize = cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.SIZE));
iResultText.setText(recordedVideoFilePath);
Log.i("videoFilePath", recordedVideoFilePath);
Log.i("videoSize", ""+recordedVideoFileSize);
上面的返回参数data,也会因为用户是否设置MediaStore.EXTRA_OUTPUT参数而改变,假设没有通过EXTRA_OUTPUT设置路径,data.getData返回的Uri为content://media/external/video/media/*,*个数字,代表具体的记录号,通过managedQuery可以获取到路径,假如设置了EXTRA_OUTPUT的话(比如/sdcard/test.3gp),则data.getData返回的Uri则为file:///sdcard/test.3gp,但是该文件居然是空白内容(不知道是不是跟手机有关,也没有在其它手机上验证过)。
根据Camera API实现自己的拍照和摄像程序
通过上面对调用系统Camera App实现拍照和摄像功能的例子,我们发现虽然能够满足我们的需求,但是毕竟自由度降低了,而且拍照的界面就是系统的样子,现在很多拍照程序,比如火爆的Camera 360软件等,就需要根据SDK提供的Camera API来编写自己的程序。
准备工作
上面调用系统Camera App,我们压根不需要任何权限,但是这里用Camera API,就必须在manifest内声明使用权限,通常由以下三项
一般拍照和摄像的时候需要写到sd卡上,所以还有一向权限声明如下
  
真做摄像功能时,需要音频录制和视频录制功能,所以又需要下面两项权限声明
  
另外使用Camera API拍照或摄像,都需要用到预览,预览就要用到SurfaceView,为此Activity的布局中必须有SurfaceView。
拍照流程
上面简单介绍了下准备工作,下面结合拍照过程中的需要用到的API对拍照流程做下简单描述
1、在Activity的OnCreate函数中设置好SurfaceView,包括设置SurfaceHolder.Callback对象和SurfaceHolder对象的类型,具体如下
SurfaceView mpreview = (SurfaceView) this.findViewById(R.id.camera_preview);
SurfaceHolder mSurfaceHolder = mpreview.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
2、在SurfaceHolder.Callback的surfaceCreated函数中,使用Camera的Open函数开启摄像头硬件,这个API在SDK 2.3之前,是没有参数的,2.3以后支持多摄像头,所以开启前可以通过getNumberOfCameras先获取摄像头数目,再通过getCameraInfo得到需要开启的摄像头id,然后传入Open函数开启摄像头,假如摄像头开启成功则返回一个Camera对象,否则就抛出异常;
3、开启成功的情况下,在SurfaceHolder.Callback的surfaceChanged函数中调用getParameters函数得到已打开的摄像头的配置参数Parameters对象,如果有需要就修改对象的参数,然后调用setParameters函数设置进去(SDK2.2以后,还可以通过Camera::setDisplayOrientation设置方向);
4、同样在surfaceChanged函数中,通过Camera::setPreviewDisplay为摄像头设置SurfaceHolder对象,设置成功后调用Camera::startPreview函数开启预览功能,上面3,4两步的代码可以如下所示
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
//已经获得Surface的width和height,设置Camera的参数
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
List vSizeList = parameters.getSupportedPictureSizes();
for(int num = 0; num < vSizeList.size(); num++)
{
Size vSize = vSizeList.get(num);
}
if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
{
//如果是竖屏
parameters.set("orientation", "portrait");
//在2.2以上可以使用
//camera.setDisplayOrientation(90);
}
else
{
parameters.set("orientation", "landscape");
//在2.2以上可以使用
//camera.setDisplayOrientation(0);
}
camera.setParameters(parameters);
try {
//设置显示
camera.setPreviewDisplay(holder);
} catch (IOException exception) {
camera.release();
camera = null;
}
//开始预览
camera.startPreview();
}
5、假设要支持自动对焦功能,则在需要的情况下,或者在上述surfaceChanged调用完startPreview函数后,可以调用Camera.autoFocus函数来设置自动对焦回调函数,该步是可选操作,有些设备可能不支持,可以通过Camera.getFocusMode函数查询。代码可以参考如下:
// 自动对焦
camera.autoFocus(new AutoFocusCallback()
{
@Override
public void onAutoFocus(boolean success, Camera camera)
{
if (success)
{
// success为true表示对焦成功,改变对焦状态图像
ivFocus.setImageResource(R.drawable.focus2);
}
}
});
6、在需要拍照的时候,调用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)函数来完成拍照,这个函数中可以四个回调接口,ShutterCallback是快门按下的回调,在这里我们可以设置播放“咔嚓”声之类的操作,后面有三个PictureCallback接口,分别对应三份图像数据,分别是原始图像、缩放和压缩图像和JPG图像,图像数据可以在PictureCallback接口的void onPictureTaken(byte[] data, Camera camera)中获得,三份数据相应的三个回调正好按照参数顺序调用,通常我们只关心JPG图像数据,此时前面两个PictureCallback接口参数可以直接传null;
7、每次调用takePicture获取图像后,摄像头会停止预览,假如需要继续拍照,则我们需要在上面的PictureCallback的onPictureTaken函数末尾,再次调用Camera.startPreview函数;
8、在不需要拍照的时候,我们需要主动调用Camera.stopPreview函数停止预览功能,并且调用Camera.release函数释放Camera,以便其他应用程序调用。SDK中建议放在Activity的Pause函数中,但是我觉得放在surfaceDestroyed函数中更好,示例代码如下
// 停止拍照时调用该方法
public void surfaceDestroyed(SurfaceHolder holder)
{
// 释放手机摄像头
camera.release();
}
以上就是自己实现拍照程序的的流程,一般还可以还可以获取预览帧的图像数据,可以分别通过Camera.setPreviewCallback和Camera.setOneShotPreviewCallback来设置每帧或下一帧图像数据的回调,这里就不做展开了。
摄像流程
摄像流程也是需要预览的,而且流程上与拍照流程在起始的1~4步流程和结束的8流程是一样的,唯一不同的是6和7两个步骤,至于5自动对焦本身就是可选的,在摄像流程也没必要。
6、开启视频录制,需要创建一个MediaRecorder对象,并调用Camera.unLock操作解锁摄像头,因为默认Camera都是锁定的,只有解锁后MediaRecorder等多媒体进程调用,并设置一些参数,然后调用MediaRecorder. start开启录制具体可以参阅如下代码:
MediaRecorder mMediaRecorder = new MediaRecorder();
// Unlock the camera object before passing it to media recorder.
camera.unlock();
mMediaRecorder.setCamera(camera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setProfile(mProfile);
mMediaRecorder.setMaxDuration(100000);//ms为单位
long dateTaken = System.currentTimeMillis();
Date date = new Date(dateTaken);
SimpleDateFormat dateFormat = new SimpleDateFormat(getString(R.string.video_file_name_format));
String title = dateFormat.format(date);
String filename = title + ".3gp"; // Used when emailing.
String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME;
String filePath = cameraDirPath + "/" + filename;
File cameraDir = new File(cameraDirPath);
cameraDir.mkdirs();
mMediaRecorder.setOutputFile(filePath);
try {
mMediaRecorder.prepare();
mMediaRecorder.start(); // Recording is now started
} catch (RuntimeException e) {
Log.e(TAG, "Could not start media recorder. ", e);
return;
}
7、上面设置了最大间隔为100s,当100是视频录制结束,录制就会被停止,如果没有设时长和文件大小限制,那么通常需要调用MediaRecorder.stop函数主动停止视频的录制,并将Camera对象通过lock函数继续加锁,示例代码如下
mMediaRecorder.stop();
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
if(camera != null)
camera.lock();
之后的操作根据交互要么重新录制要么就释放Camera对象回到拍照流程的8步骤了。在这里就不做赘述了。
使用和整理过程中,由于英文不太好,非常感谢网上的一篇SDK中文翻译,链接地址如下
http://blog.csdn.net/raindrophust/article/details/6205038
另外Android开发,最佳借鉴,我觉得还是源码,Camera的很多参数和使用方法可以参照源码中Camera APP的源码,目录为packages\apps\Camera。

3.个人使用总结:
网址:http://www.cnblogs.com/bausch/archive/2011/10/20/2219068.html
android大扫盲之SurfaceView,SurfaceHolder,SurfaceHolder.CallBack
最近接触到了SurfaceView,SurfaceHolder,SurfaceHolder.CallBack,一直不求其解,现在来粗浅认识一下它们。
先看一下官方的定义:
1.SurfaceView
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。
  你可以通过SurfaceHolder接口访问这个Surface.用getHolder()方法可以得到这个接口。
surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。
surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:
1> 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。
2> 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。
2.SurfaceHolder
显示一个surface的抽象接口,使你可以控制surface的大小和格式, 以及在surface上编辑像素,和监视surace的改变。这个接口通常通过SurfaceView类实现。
3. SurfaceHolder.Callback
用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时,  它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。设置Callback的方法是SurfaceHolder.addCallback.


马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册 

关键技术:录制视频计时器自动对焦调整焦距选择录制分辨率,还有操作延迟等等
废话不多说,视频录制,开始:
1.准备一个自定义的SurfaceView
  1. import java.io.IOException;

  2. import android.content.Context;
  3. import android.graphics.PixelFormat;
  4. import android.hardware.Camera;
  5. import android.util.Log;
  6. import android.view.SurfaceHolder;
  7. import android.view.SurfaceView;

  8. public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
  9.     private SurfaceHolder mHolder;
  10.     private Camera mCamera;

  11.     public CameraPreview(Context context) {
  12.                 super(context);
  13.         }

  14.         @SuppressWarnings("deprecation")
  15.         public CameraPreview(Context context, Camera camera) {
  16.         super(context);
  17.         mCamera = camera;

  18.         // Install a SurfaceHolder.Callback so we get notified when the
  19.         // underlying surface is created and destroyed.
  20.         mHolder = getHolder();
  21.         mHolder.addCallback(this);
  22.         mHolder.setFormat(PixelFormat.TRANSPARENT);
  23.                 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  24.         // deprecated setting, but required on Android versions prior to 3.0
  25.     }

  26.     public void surfaceCreated(SurfaceHolder holder) {
  27.         // The Surface has been created, now tell the camera where to draw the preview.
  28.         try {
  29.             mCamera.setPreviewDisplay(holder);
  30.             
  31.         } catch (IOException e) {
  32.             Log.d("视频加载错误", "Error setting camera preview: " + e.getMessage());
  33.         }
  34.     }

  35.     public void surfaceDestroyed(SurfaceHolder holder) {
  36.         // empty. Take care of releasing the Camera preview in your activity.
  37.             // stop preview before making changes
  38.         try {
  39.             mCamera.stopPreview();
  40.         } catch (Exception e){
  41.           // ignore: tried to stop a non-existent preview
  42.         }
  43.     }

  44.     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
  45.         // If your preview can change or rotate, take care of those events here.
  46.         // Make sure to stop the preview before resizing or reformatting it.

  47.         if (mHolder.getSurface() == null){
  48.           // preview surface does not exist
  49.           return;
  50.         }

  51.         // set preview size and make any resize, rotate or
  52.         // reformatting changes here

  53.         // start preview with new settings
  54.         try {
  55. //            mCamera.setPreviewDisplay(mHolder);
  56.             mCamera.startPreview();

  57.         } catch (Exception e){
  58.          //   Log.d(TAG, "Error starting camera preview: " + e.getMessage());
  59.         }
  60.     }
  61. }
复制代码

2.实例化你的SurfaceView,并把打开的camera放进去
  1. camera = Camera.open();
  2.                 preview = new CameraPreview(this, camera);
  3.                 preview.setFocusable(false);
  4.                 preview.setEnabled(false);
复制代码

3.得到camera中的参数设置项,进行相应的设置
  1. cameraParams = camera.getParameters();
  2.                 if (VERSION.SDK_INT >= 14) {
  3.                         cameraParams.setFocusMode("auto");
  4.                         camera.autoFocus(myAutoFocusCallback);
  5.                 } else {
  6.                         cameraParams
  7.                                         .setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
  8.                         isVideoAuto = false;
  9.                 }

  10.                 List<Size> tempList = cameraParams.getSupportedPreviewSizes();
  11.                 if (tempList != null && tempList.size() > 0) {
  12.                         for (int i = 0; i < tempList.size(); i++) {
  13.                                 widthArray.put(i, tempList.get(i).width);
  14.                                 heightArray.put(i, tempList.get(i).height);
  15.                         }
  16.                         setVideoSize();
  17.                 } else {
  18.                         isVideoSizeSupport = false;
  19.                         videoSizeLayout.setVisibility(View.GONE);
  20.                 }

  21.                 cameraParams.setRotation(90);
  22.                 camera.setParameters(cameraParams);
  23.                 try {
  24.                         camera.setPreviewDisplay(preview.getHolder());
  25.                 } catch (IOException e1) {
  26.                         e1.printStackTrace();
  27.                 }
复制代码

4.把你准备好的自定义SurfaceView放到一个容器中,此处用layout
  1. layout.addView(preview);
  2. layout.setOnTouchListener(this);//这里添加触摸事件是为了触摸对焦做准备
复制代码

5.视频录制的一些参数设置
  1. camera.startPreview();
  2.                 camera.unlock();// 解锁后才能调用,否则报错
  3.                 mediaRecorder = new MediaRecorder();
  4.                 mediaRecorder.setCamera(camera);// 将camera添加到视频录制端口
  5.                 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 音麦
  6.                 mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 视频源
  7.                 mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 输出格式
  8.                 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 声音源码
  9.                 mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// 视频源码
  10.                 if (isVideoSizeSupport) {
  11.                         mediaRecorder.setVideoSize(widthArray.get(sizeIndex),
  12.                                         heightArray.get(sizeIndex));//设置系统支持的分辨率
  13.                 } else {
  14.                         mediaRecorder.setVideoSize(320, 240);
  15.                 }
  16.                 mediaRecorder.setVideoFrameRate(3);//设置帧数

  17.                 mediaRecorder.setPreviewDisplay(preview.getHolder().getSurface());
复制代码
6.开始录制视频,并且打开视频的计时器
  1. try {
  2.                         mediaRecorder.prepare();
  3.                         timer.setVisibility(View.VISIBLE);
  4.                         handler.postDelayed(task, 1000);
  5.                 } catch (IllegalStateException e) {
  6.                         e.printStackTrace();
  7.                 } catch (IOException e) {
  8.                         e.printStackTrace();
  9.                 }
  10.                 try {
  11.                         mediaRecorder.start();
  12.                         Toast.makeText(this, "开始录制", Toast.LENGTH_SHORT).show();
  13.                 } catch (IllegalStateException e) {
  14.                         this.finish();
  15.                         Toast.makeText(this, "不能录制视频!", Toast.LENGTH_SHORT).show();
  16.                 }
复制代码

7.实例化一个竖直的seekbar,然后把支持的最大调整焦距设定成seekbar的最大值,然后添加seekbar的滑动事件
  1. int max = camera.getParameters().getMaxZoom();
  2.                 if (max == 0) {
  3.                         mZoomBar.setVisibility(View.GONE);
  4.                 } else {
  5.                         mZoomBar.setMax(max);
  6.                         mZoomBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
  7.                                 public void onStopTrackingTouch(SeekBar seekBar) {

  8.                                 }

  9.                                 public void onStartTrackingTouch(SeekBar seekBar) {
  10.                                 }

  11.                                 public void onProgressChanged(SeekBar seekBar, int progress,
  12.                                                 boolean fromUser) {
  13.                                         try {
  14.                                                 if (camera != null && cameraParams.isZoomSupported()) {
  15.                                                         if (cameraParams.isSmoothZoomSupported()) {
  16.                                                                 camera.startSmoothZoom(progress);
  17.                                                         } else {
  18.                                                                 Log.e("VideoCameraActivity", "不支持智能变焦");
  19.                                                                 cameraParams.setZoom(progress);
  20.                                                                 camera.setParameters(cameraParams);
  21.                                                         }
  22.                                                 }
  23.                                         } catch (Exception e) {
  24.                                                 mZoomBar.setVisibility(View.GONE);
  25.                                         }
  26.                                 }
  27.                         });
  28.                 }
复制代码

8.触摸对焦的关键代码
  1. @Override
  2.         public boolean onTouch(View v, MotionEvent event) {
  3.                 if (event.getAction() == MotionEvent.ACTION_UP) {
  4.                         if (camera != null && isVideoAuto) {
  5.                                 float x = event.getX();
  6.                                 float y = event.getY();
  7.                                 float touchMajor = event.getTouchMajor();
  8.                                 float touchMinor = event.getTouchMinor();

  9.                                 Rect touchRect = new Rect((int) (x - touchMajor / 2),
  10.                                                 (int) (y - touchMinor / 2), (int) (x + touchMajor / 2),
  11.                                                 (int) (y + touchMinor / 2));

  12.                                 this.submitFocusAreaRect(touchRect);
  13.                         }
  14.                 }
  15.                 return false;
  16.         }

  17.         private void submitFocusAreaRect(final Rect touchRect) {
  18.                 Camera.Parameters cameraParameters = camera.getParameters();
  19.                 if (cameraParameters == null
  20.                                 || cameraParameters.getMaxNumFocusAreas() == 0) {
  21.                         return;
  22.                 }

  23.                 // Convert from View's width and height to +/- 1000
  24.                 Rect focusArea = new Rect();
  25.                 focusArea.set(touchRect.left * 2000 / preview.getWidth() - 1000,
  26.                                 touchRect.top * 2000 / preview.getHeight() - 1000,
  27.                                 touchRect.right * 2000 / preview.getWidth() - 1000,
  28.                                 touchRect.bottom * 2000 / preview.getHeight() - 1000);
  29.                 // Submit focus area to camera
  30.                 ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
  31.                 focusAreas.add(new Camera.Area(focusArea, 1000));
  32.                 cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
  33.                 cameraParameters.setFocusAreas(focusAreas);
  34.                 try {
  35.                         camera.setParameters(cameraParameters);
  36.                         camera.autoFocus(myAutoFocusCallback);
  37.                 } catch (Exception e) {
  38.                         e.printStackTrace();
  39.                 }
  40.         }
复制代码

9.分辨率设置
  1. public void onRealution(View view) {
  2.                 if (isTaking) {
  3.                         Toast.makeText(this, "录制视频不允许切换视频尺寸", Toast.LENGTH_SHORT).show();
  4.                 } else {
  5.                         final Dialog dialog = new Dialog(this);
  6.                         ListView listView = new ListView(this);
  7.                         listView.setCacheColorHint(Color.TRANSPARENT);
  8.                         listView.setBackgroundColor(Color.WHITE);
  9.                         if (adapter == null)
  10.                                 adapter = new VideoSizeAdapter(this, widthArray, heightArray);
  11.                         listView.setAdapter(adapter);
  12.                         listView.setOnItemClickListener(new OnItemClickListener() {
  13.                                 @Override
  14.                                 public void onItemClick(AdapterView<?> arg0, View arg1,
  15.                                                 int arg2, long arg3) {
  16.                                         adapter.index = arg2;
  17.                                         sizeIndex = arg2;
  18.                                         setVideoSize();
  19.                                         dialog.dismiss();
  20.                                 }
  21.                         });
  22.                         dialog.setTitle("分辨率设置");
  23.                         dialog.setContentView(listView);
  24.                         dialog.setCanceledOnTouchOutside(true);
  25.                         dialog.show();
  26.                 }
  27.         }

用录像机功能的代码如下:Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0.9);//限制时长intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 5);//限制大小intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024*1024);startActivityForResult(intent, 11);遇到的问题是:1   intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,0);这个参数有效值是0的时候画面质量低的不像话, 当值是1的时候1秒钟消耗2M存储空间.都不合适,当我把值设置为零点几的时候,效果和设置0是一样的, 有没有中间参数可用啊! 就是让质量和大小能均衡一下2  设置时间长度限制,设置文件大小限制都不起作用,求解啊!!!!!!





0 0
原创粉丝点击