现在的位置: 首页 > 综合 > 正文

SurfaceView显示Camera摄像(之二设置参数、变焦)

2013年08月05日 ⁄ 综合 ⁄ 共 7210字 ⁄ 字号 评论关闭

上次已经写过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用来实现调焦的

抱歉!评论已关闭.