上次已经写过SurfaceView显示Camera摄像了,代码可以运行,但是里面有问题,这次纠正过来,顺便实现变焦:
代码:
public class CameravedioActivity extends Activity{ private static final String TAG = "CameravedioActivity"; private Camera camera; private boolean preview = false ; private SeekBar mSeekBar; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* *设置窗口属性:一定要在 setContentView(R.layout.main) 之前 */ // 窗口标题,其实可以在manifes文件里面注册 // requestWindowFeature(Window.FEATURE_NO_TITLE); // 全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.main); surfaceView = (SurfaceView) findViewById(R.id.surfaceView); surfaceHolder = surfaceView.getHolder(); surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); surfaceView.getHolder().setFixedSize(200, 200); surfaceView.getHolder().addCallback(new SurfaceViewCallback()); /** * seekbar 用来实现变焦逻辑 */ mSeekBar = (SeekBar)findViewById(R.id.seekbar); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // TODO Auto-generated method stub Log.d(TAG, "progress:"+progress); // sdk 文档描述 set zoom 之前先check if(camera.getParameters().isZoomSupported()){ Parameters params = camera.getParameters(); params.setZoom(progress); camera.setParameters(params); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub Log.d(TAG, "onStartTrackingTouch"); } @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub Log.d(TAG, "onStartTrackingTouch"); } }); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); } public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); int degrees = 0; Log.d(TAG, "rotation:"+rotation); switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } private final class SurfaceViewCallback implements Callback { /** * surfaceView 被创建成功后调用此方法 */ @Override public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG,"surfaceCreated"); /* * 在SurfaceView创建好之后 打开摄像头 * 注意是 android.hardware.Camera */ // 2.2获取摄像头number physical cameras // api 9: Camera.getNumberOfCameras() Log.d(TAG, "numbers:"+Camera.getNumberOfCameras()); if(Camera.getNumberOfCameras() ==2){ // 前置摄像头 // api 9 :Camera.CameraInfo camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT); camera.setDisplayOrientation(90); }else{ camera = Camera.open(); } // camera = Camera.open(); // setCameraDisplayOrientation(CameravedioActivity.this,Camera.CameraInfo.CAMERA_FACING_FRONT,camera); Log.d(TAG, "smoothZoom:"+camera.getParameters().isSmoothZoomSupported()); Log.d(TAG, "supportzoom:"+camera.getParameters().isZoomSupported()); Log.d(TAG, "max zoom:"+camera.getParameters().getMaxZoom()); /* * This method must be called before startPreview(). otherwise surfaceview没有图像 */ try { camera.setPreviewDisplay(surfaceHolder); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Camera.Parameters parameters = camera.getParameters(); /* 每秒从摄像头捕获5帧画面, */ parameters.setPreviewFrameRate(5); /* 设置照片的输出格式:jpg */ parameters.setPictureFormat(PixelFormat.JPEG); /* 照片质量 */ parameters.set("jpeg-quality", 85); mSeekBar.setMax(parameters.getMaxZoom()); // valid parameters: // 取得相机所支持多少图片大小的个数 List<Size> pszize = parameters.getSupportedPreviewSizes(); // List<Size> pszize = parameters.getSupportedPictureSizes(); if (null != pszize && 0 < pszize.size()) { int height[] = new int[pszize.size()];// 声明一个数组 Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (int i = 0; i < pszize.size(); i++) { Size size = (Size) pszize.get(i); int sizeheight = size.height; int sizewidth = size.width; height[i] = sizeheight; map.put(sizeheight, sizewidth); Log.d(TAG, "size.width:"+sizewidth+"\tsize.height:"+sizeheight); } Arrays.sort(height); // 设置 // parameters.setPictureSize(map.get(height[0]),height[0]); parameters.setPreviewSize(map.get(height[0]),height[0]); } /* 将参数对象赋予到 camera 对象上 */ camera.setParameters(parameters); camera.startPreview(); /** * Installs a callback to be invoked for every preview frame in addition to displaying them on the screen. * The callback will be repeatedly called for as long as preview is active. This method can be called at * any time, even while preview is live. Any other preview callbacks are overridden. * a callback object that receives a copy of each preview frame, or null to stop receiving */ camera.setPreviewCallback(new Camera.PreviewCallback(){ @Override public void onPreviewFrame(byte[] data, Camera camera) { // TODO Auto-generated method stub //在视频聊天中,这里传送本地frame数据给remote端 // Log.d(TAG, "camera:"+camera); // Log.d(TAG, "byte:"+data); } }); preview = true; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d(TAG,"surfaceChanged"); } /** * SurfaceView 被销毁时释放掉 摄像头 */ @Override public void surfaceDestroyed(SurfaceHolder holder) { if(camera != null) { /* 若摄像头正在工作,先停止它 */ if(preview) { camera.stopPreview(); preview = false; } //如果注册了此回调,在release之前调用,否则release之后还回调,crash camera.setPreviewCallback(null); camera.release(); } } } }注册文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.edu.wtu" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <!-- android:screenOrientation="landscape" 表示横向界面 --> <activity android:name=".CameravedioActivity" android:label="@string/app_name" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="7" /> <!-- 在SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 往SDCard写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- 申请使用摄像头的权限 --> <uses-permission android:name="android.permission.CAMERA"/> </manifest>
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <SurfaceView android:id="@+id/surfaceView" android:layout_width="200dip" android:layout_height="150dip" android:layout_gravity="center" android:visibility="visible" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <SeekBar android:id="@+id/seekbar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="40dip" android:layout_marginRight="40dip" android:layout_gravity="center" android:progressDrawable="@android:color/transparent" android:background="@drawable/progressbar_box" /> </LinearLayout> </LinearLayout> </FrameLayout>seekbar用来实现调焦的