一,调用系统相机
1,用最简单的方式拍到一张照片返回到当前页面
a,在布局里添加一个按钮和imageview,可以通过设置按钮的onclick 属性绑定一个方法
b,在按钮的绑定方法里写如下内容:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQ_1);
这个intent 可以让我们跳转到系统相机的页面,REQ_1 是自定义的整型变量
c,在获得返回值方法里,添加下面内容,比较简洁就不做过多解释:
if (resultCode == RESULT_OK && requestCode == REQ_1) { Bundle bundle = data.getExtras(); Bitmap bitmap = (Bitmap) bundle.get("data"); imageView.setImageBitmap(bitmap); }
里面出现的data 这个名字应该是系统设定的,运行程序就能看到效果,这里看到的照片实际是真实照片的缩略图
2, 调用系统相机返回一张清晰的照片,思路是:调用系统相机时,给出一个照片存放的路径,拍完后,按照路径来找到真实的照片。
a,我们需要提前设置存放照片的路径
String imgpath = Environment.getExternalStorageDirectory().getPath(); imgpath = imgpath + "/" + "temp.png";
b, 开始跳转,并传入需要设定的路径
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri uri = Uri.fromFile(new File(imgpath)); // 用路径生成一个android 包下的Uri intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);// 设置照片存储路径 startActivityForResult(intent, REQ_2);
这一步需要添加访问sd卡的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
c,在获得返回值的方法里,从路径读取照片
FileInputStream fileInputStream = new FileInputStream(imgpath); Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream); imageView.setImageBitmap(bitmap);这里的imgpath 就是一个字符串变量,里面保存的是之前设置的路径,这里因为设计io流,所以需要抓去异常,包围try/catch就可以了
然后就可以运行程序试试了,这里可能存在高的安卓系统出现不兼容问题,我在模拟器上可以运行,在手机就会报错
二,一个自定义的相机,能够返回一个清晰的照片
1, 添加基础元素
a,在布局文件里,添加surfaceView 布局,ImageView布局,一个按钮
b,声明一个Camera对象,并进行实例化
Camera camera = Camera.open();
c ,建立一些必要的对象,这里需要让activity 实现 SurfaceHolder.Callback接口
private SurfaceView surfaceView; private SurfaceHolder surfaceHolder;
surfaceView = (SurfaceView)findViewById(R.id.preview); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this);
d. 对Camera进行预览:
camera.setPreviewDisplay(holder); //将系统camera 预览角度旋转90度 camera.setDisplayOrientation(90); camera.startPreview();
其中的holder就是上文中的surfaceholder
在按钮的绑定方法中添加如下内容
Camera.Parameters parameters = camera.getParameters(); // 利用Parameters对相机的参数进行设置 parameters.setPictureFormat(ImageFormat.JPEG); //设置照片格式 Camera.Size size = parametersset(camera); // 这里利用自定义函数parametersset()获得相机支持的最大图片大小 parameters.setPictureSize(size.width,size.height);// 对图片的大小进行设置,越大则图片越清晰 parameters.setJpegQuality(100);//设置照片质量,1-100, parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);// 设置照片对焦方式 camera.setParameters(parameters);// 让相机的对象完成刚才的设置
camera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean b, Camera camera) { if (b){ camera.takePicture(null,null,pictureCallback); } } });
public Camera.Size parametersset(Camera camera) { // 获取相机所支持的最大照片大小 List<Camera.Size> pictureSizes = camera.getParameters().getSupportedPictureSizes(); Camera.Size psize=null; for (int i = 0; i < pictureSizes.size(); i++) { psize = pictureSizes.get(i); } return psize; }
这里面的pictureCallback对象需要提前声明一下
private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] bytes, Camera camera) { File file = new File("/sdcard/temp.png"); filepath = file.getAbsolutePath(); try { FileOutputStream fileOutputStream = new FileOutputStream(file); fileOutputStream.write(bytes); fileOutputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } };
最后还需要在程序终止时对相机进行关闭
@Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { if( camera !=null) { camera.setPreviewCallback(null); // 将相机的回调置空,取消surfaceview 和相机的关联操作 camera.stopPreview();//取消相机的取景功能 camera.release();//释放相机所占用的系统资源 camera=null; } } }
再就是权限设置了
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" />
相机和sd卡的权限
到这里就结束了,如果还不太清楚的可以看我的博客里的源代码,名称为CameraTest