Android多媒体学习三:实现自己的Camera
16lz
2022-07-21
Android自带的Camera应用虽然可以满足大多数情景,但是其灵活性上还有不足。但是Android允许我们定制自己的Camera。
在Android的hardware包中有一个Camera类。这个类就是获取Camera服务的,可以定制Camera等。
可以通过open()方法获取其实例。
在使用这个类是需要在AndroidManifest.xml文件中加入相应的权限和特性
如:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
等。
本文实例:
- packagedemo.camera;
- importjava.io.OutputStream;
- importjava.util.Iterator;
- importjava.util.List;
- importandroid.app.Activity;
- importandroid.content.ContentValues;
- importandroid.content.res.Configuration;
- importandroid.hardware.Camera;
- importandroid.net.Uri;
- importandroid.os.Bundle;
- importandroid.provider.MediaStore;
- importandroid.view.SurfaceHolder;
- importandroid.view.SurfaceView;
- importandroid.view.View;
- importandroid.widget.LinearLayout;
- /**
- *Android自带的Camera应用程序可以完成很多功能。但是当其不能满足我们需要的时候
- *我们可以定制自己的Camera。Android提供了Camera类来辅助我们实现自己的Camera。
- *这个例子就来定义一个自己的Camera
- *首先,在Manifest中需要引入权限<uses-permissionandroid:name="android:permission.CAMERA"/>
- *我们需要用来存放取景器的容器,这个容器就是SurfaceView。
- *使用SurfaceView的同时,我们还需要使用到SurfaceHolder,SurfaceHolder相当于一个监听器,可以监听
- *Surface上的变化,通过其内部类CallBack来实现。
- *为了可以获取图片,我们需要使用Camera的takePicture方法同时我们需要实现Camera.PictureCallBack类,实现onPictureTaken方法
- *@authorAdministrator
- *
- */
- publicclassMyCameraextendsActivityimplementsSurfaceHolder.Callback,Camera.PictureCallback{
- publicstaticfinalintMAX_WIDTH=200;
- publicstaticfinalintMAX_HEIGHT=200;
- privateSurfaceViewsurfaceView;
- privateCameracamera;//这个是hardare的Camera对象
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- this.setContentView(R.layout.camera);
- surfaceView=(SurfaceView)this.findViewById(R.id.myCameraView);
- surfaceView.setFocusable(true);
- surfaceView.setFocusableInTouchMode(true);
- surfaceView.setClickable(true);
- surfaceView.setOnClickListener(newView.OnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- camera.takePicture(null,null,null,MyCamera.this);
- }
- });
- //SurfaceView中的getHolder方法可以获取到一个SurfaceHolder实例
- SurfaceHolderholder=surfaceView.getHolder();
- //为了实现照片预览功能,需要将SurfaceHolder的类型设置为PUSH
- //这样,画图缓存就由Camera类来管理,画图缓存是独立于Surface的
- holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
- holder.addCallback(this);
- }
- @Override
- publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intw,inth){
- }
- @Override
- publicvoidsurfaceCreated(SurfaceHolderholder){
- //当Surface被创建的时候,该方法被调用,可以在这里实例化Camera对象
- //同时可以对Camera进行定制
- camera=Camera.open();//获取Camera实例
- /**
- *Camera对象中含有一个内部类Camera.Parameters.该类可以对Camera的特性进行定制
- *在Parameters中设置完成后,需要调用Camera.setParameters()方法,相应的设置才会生效
- *由于不同的设备,Camera的特性是不同的,所以在设置时,需要首先判断设备对应的特性,再加以设置
- *比如在调用setEffects之前最好先调用getSupportedColorEffects。如果设备不支持颜色特性,那么该方法将
- *返回一个null
- */
- try{
- Camera.Parametersparam=camera.getParameters();
- if(this.getResources().getConfiguration().orientation!=Configuration.ORIENTATION_LANDSCAPE){
- //如果是竖屏
- param.set("orientation","portrait");
- //在2.2以上可以使用
- //camera.setDisplayOrientation(90);
- }else{
- param.set("orientation","landscape");
- //在2.2以上可以使用
- //camera.setDisplayOrientation(0);
- }
- //首先获取系统设备支持的所有颜色特效,有复合我们的,则设置;否则不设置
- List<String>colorEffects=param.getSupportedColorEffects();
- Iterator<String>colorItor=colorEffects.iterator();
- while(colorItor.hasNext()){
- StringcurrColor=colorItor.next();
- if(currColor.equals(Camera.Parameters.EFFECT_SOLARIZE)){
- param.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);
- break;
- }
- }
- //设置完成需要再次调用setParameter方法才能生效
- camera.setParameters(param);
- camera.setPreviewDisplay(holder);
- /**
- *在显示了预览后,我们有时候希望限制预览的Size
- *我们并不是自己指定一个SIze而是指定一个Size,然后
- *获取系统支持的SIZE,然后选择一个比指定SIZE小且最接近所指定SIZE的一个
- *Camera.Size对象就是该SIZE。
- *
- */
- intbestWidth=0;
- intbestHeight=0;
- List<Camera.Size>sizeList=param.getSupportedPreviewSizes();
- //如果sizeList只有一个我们也没有必要做什么了,因为就他一个别无选择
- if(sizeList.size()>1){
- Iterator<Camera.Size>itor=sizeList.iterator();
- while(itor.hasNext()){
- Camera.Sizecur=itor.next();
- if(cur.width>bestWidth&&cur.height>bestHeight&&cur.width<MAX_WIDTH&&cur.height<MAX_HEIGHT){
- bestWidth=cur.width;
- bestHeight=cur.height;
- }
- }
- if(bestWidth!=0&&bestHeight!=0){
- param.setPreviewSize(bestWidth,bestHeight);
- //这里改变了SIze后,我们还要告诉SurfaceView,否则,Surface将不会改变大小,进入Camera的图像将质量很差
- surfaceView.setLayoutParams(newLinearLayout.LayoutParams(bestWidth,bestHeight));
- }
- }
- camera.setParameters(param);
- }catch(Exceptione){
- //如果出现异常,则释放Camera对象
- camera.release();
- }
- //启动预览功能
- camera.startPreview();
- }
- @Override
- publicvoidsurfaceDestroyed(SurfaceHolderholder){
- //当Surface被销毁的时候,该方法被调用
- //在这里需要释放Camera资源
- camera.stopPreview();
- camera.release();
- }
- @Override
- publicvoidonPictureTaken(byte[]data,Cameracamera){
- //data是一个原始的JPEG图像数据,
- //在这里我们可以存储图片,很显然可以采用MediaStore
- //注意保存图片后,再次调用startPreview()回到预览
- UriimageUri=this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,newContentValues());
- try{
- OutputStreamos=this.getContentResolver().openOutputStream(imageUri);
- os.write(data);
- os.flush();
- os.close();
- }catch(Exceptione){
- //TODO:handleexception
- e.printStackTrace();
- }
- camera.startPreview();
- }
- }
更多相关文章
- 浅谈Java中Collections.sort对List排序的两种方法
- Python list sort方法的具体使用
- python list.sort()根据多个关键字排序的方法实现
- android上一些方法的区别和用法的注意事项
- android实现字体闪烁动画的方法
- Android(安卓)Wifi模块分析(三)
- Android中dispatchDraw分析
- 使用NetBeans搭建Android开发环境
- Android四大基本组件介绍与生命周期