安卓之相机Camera(二)

之前说过的,调用手机摄像头拍照除了调用系统的照相之外,也可以自己去自定义我们的相机软件。这里开始看官方api觉得云里雾里的,现在看懂了,恍然大悟,其实官方都已经给我们罗列了核心的方法和思路。

1 首先,因为是自定义的,所以需要给我们的manifest文件加上一些必要的权限。

 <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"/>
2 我们来定义这样的一个视图,用来显示的,这个类中我们通过外部去传入camera对象,然后对camera进行一些必要的设置,通过mCamera.startPreview();方法来进行捕捉视图,里面的方法在官方文档中都是有的,我也就是复制过来的。没什么说的,另外实现SurfaceHolder.Callback这个接口,复写三个方法,分别用于不同阶段进行一些处理

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
	 

	private SurfaceHolder mHolder;
	private Camera mCamera;
	
	 public CameraPreview(Context context, Camera camera) {
			super(context);
			mCamera = camera;
			mHolder = getHolder();
			mHolder.addCallback(this);
			mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		}


	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		 try {
			mCamera.setPreviewDisplay(holder);
			mCamera.setDisplayOrientation(90); 
			mCamera.startPreview();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		if (mHolder.getSurface() == null){
	          // preview surface does not exist
	          return;
	        }

	        // stop preview before making changes
	        try {
	            mCamera.stopPreview();
	        } catch (Exception e){
	          // ignore: tried to stop a non-existent preview
	        }

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

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

	        } catch (Exception e){
	        	
	        }
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		
	}
}
3 mainActivity的布局文件  framelayout用来添加自定义的view,两个按钮分别用于拍照 和继续拍照

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />
<LinearLayout 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >
    <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
     <Button
    android:id="@+id/button_cancle"
    android:text="Cancle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
    <ImageView 
        android:id="@+id/iv"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:scaleType="fitXY"
        />
    
</LinearLayout>
  
  
</LinearLayout>
4 主类MainActivity

public class MainActivity extends Activity{
	private Camera mCamera;
    private CameraPreview mPreview;
    private Button button_capture;
    private ImageView iv;
    private File pictureFile;
    private Button button_cancle;
    private PictureCallback mPicture = new PictureCallback() {
<span style="white-space:pre">	</span>//向文件输出位置存放io 输出流
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

        	pictureFile = getOutputMediaFile();
            
            if (pictureFile == null){
                return;
            }

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {
            	
            } catch (IOException e) {
            	
            }
            iv.setImageURI(Uri.fromFile(pictureFile));
        }
    };
    
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		button_capture = (Button) findViewById(R.id.button_capture);
		button_cancle = (Button) findViewById(R.id.button_cancle);
		iv = (ImageView) findViewById(R.id.iv);
		if(checkCameraHardware(this)){
			mCamera = getCameraInstance();//实例化
		    mPreview = new CameraPreview(this, mCamera);//初始化
		    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);//添加自定义的view
		    preview.addView(mPreview);
		}
		button_capture.setOnClickListener(
			    new View.OnClickListener() {
			        @Override
			        public void onClick(View v) {
			            // get an image from the camera
			            mCamera.takePicture(null, null, mPicture);
			        }
			    }
			);
		button_cancle.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				mCamera.startPreview();//继续捕捉视图
			}
		});
	}
<span style="white-space:pre">	</span>//设置存放的文件路径,和之前那个一样
	protected File getOutputMediaFile() {
		String path = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"ABC";
		File file = new File(path);
		if(!file.exists()){
			file.mkdirs();
		}
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
		String imageFileName = "IMG_" + timeStamp ;
		File file2 = new File(file,imageFileName+".jpg");
		return file2;
	}
<span style="white-space:pre">	</span>//检查是否有摄像头设备 或者权限
	private boolean checkCameraHardware(Context context) {
	    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
	        // this device has a camera
	        return true;
	    } else {
	        // no camera on this device
	        return false;
	    }
	}
	//实例化 这个Camera 对象 然后传给那个自定义view
	/** A safe way to get an instance of the Camera object. */
	public static Camera getCameraInstance(){
	    Camera c = null;
	    try {
	        c = Camera.open(); // attempt to get a Camera instance
	    }
	    catch (Exception e){
	        // Camera is not available (in use or does not exist)
	    }
	    return c; // returns null if camera is unavailable
	}
	//应用关闭后 释放掉照相机 防止其他软件不能正常使用
	@Override
	protected void onDestroy() {
		mCamera.release();
		super.onDestroy();
	}
	
}
因为默认的照相机 是横屏的,官方给的是在manifest清单文件的activity标签下,加入 android:screenOrientation="landscape"这个属性,但是我个人认为这样,手机 看起来很变扭,所以没有这么做,用官方提供的,mCamera.setDisplayOrientation(90); 这个方法,是屏幕是竖直的效果,不过最后在现实图片发现,我们只是假象的以为拍摄的是竖直的,其实还是颠倒的,我通过查看那个获取的图片发现。只是给我们认为是那个样子,所以后面我们就需要将图片也翻转过来,这个暂时还没有去做。另外当我们获取了图片时,需要重新开启,通过再次调用mCamera.startPreview();这个方法。

点击下载源码




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值