调用Android系统摄像头进行拍照以及从图库选择图片
2016-06-11 14:10
966 查看
很多时候我们需要调用系统摄像头进行拍照或者从图库选择照片,然后对得到的图片进行一些处理。比如微信设置头像,就可以选择调用设备存在摄像头APP进行拍照,然后对图像进行裁剪,最终设置为头像。
下面来进行讲解。
主要分为以下几个部分:
1、获得摄像头Feature和写文件的权限
由于不需要直接操作摄像头,而只是调用存在的APP,所以不需要Camera权限,自需要获得Camera Feature即可:
如果需要把得到的图片写入外部存储,需要声明写外部存储权限:
如果需要把得到的图片写入私有存储,在Android4.3及以下,需要声明WRITE_EXTERNAL_STORAGE权限,从Android4.4开始,这个权限不再需要了,所以可以声明权限如下所示:
2、创建一个文件用来保存得到的图片
3、启动Intent进行拍照、启动Intent从图库选择照片
4、在onActivityResult回调函数里面,对图片进行处理,包括对图片进行裁剪以及显示到ImageView以及把图片加入到Media Provider's database
裁剪照片:
把图片加入Media Provider's database
下面来进行讲解。
主要分为以下几个部分:
1、获得摄像头Feature和写文件的权限
由于不需要直接操作摄像头,而只是调用存在的APP,所以不需要Camera权限,自需要获得Camera Feature即可:
<uses-feature android:name="android.hardware.camera2" android:required="true" />
如果需要把得到的图片写入外部存储,需要声明写外部存储权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
如果需要把得到的图片写入私有存储,在Android4.3及以下,需要声明WRITE_EXTERNAL_STORAGE权限,从Android4.4开始,这个权限不再需要了,所以可以声明权限如下所示:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
2、创建一个文件用来保存得到的图片
/** * 创建保存得到的图片的文件 * * @return * @throws IOException */ private File createImageFile() throws IOException { if (checkSDCardAvaliable()) { File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "CameraDemo"); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d(TAG, "failed to create directory"); return null; } } // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp; String suffix = ".jpg"; File image = new File(mediaStorageDir + File.separator + imageFileName + suffix); mCurrentPhotoPath = image.getAbsolutePath(); return image; } return null; }
3、启动Intent进行拍照、启动Intent从图库选择照片
/** * 启动拍照 */ private void startCamera() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // Ensure that there's a camera activity to handle the intent if (takePictureIntent.resolveActivity(getPackageManager()) != null) { // Continue only if the File was successfully created if (mSavePhotoFile != null) { takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mSavePhotoFile));//设置文件保存的URI startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); } } }
/** * 从图库选择照片 */ private void selectPhoto() { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, REQUEST_SELECT_PHOTO); }
4、在onActivityResult回调函数里面,对图片进行处理,包括对图片进行裁剪以及显示到ImageView以及把图片加入到Media Provider's database
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { switch (requestCode) { case REQUEST_TAKE_PHOTO: //拍照 //注意,如果拍照的时候设置了MediaStore.EXTRA_OUTPUT,data.getData=null startPhotoZoom(Uri.fromFile(mSavePhotoFile), 256, 256); break; case REQUEST_SELECT_PHOTO://选择图片 startPhotoZoom(data.getData(), 256, 256); break; case REQUEST_CROP_PHOTO: Bundle extras = data.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); //把图片显示到ImgeView iv_diaplay.setImageBitmap(photo); //把图片加入图库 galleryAddPic(); } break; } } }
裁剪照片:
/** * 裁剪照片 */ public void startPhotoZoom(Uri uri, int width, int height) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 设置裁剪 intent.putExtra("crop", "true"); intent.putExtra("scale", true);// 去黑边 // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", width/height); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", width); intent.putExtra("outputY", height); // 图片格式 intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true);// 取消人脸识别 intent.putExtra("return-data", true);// true:返回uri,false:不返回uri // 同一个地址下 裁剪的图片覆盖之前得到的图片 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mSavePhotoFile)); startActivityForResult(intent, REQUEST_CROP_PHOTO); }
把图片加入Media Provider's database
/** * 触发系统的media scanner来把图片加入Media Provider's database */ private void galleryAddPic() { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); File f = new File(mCurrentPhotoPath);// Uri contentUri = Uri.fromFile(f); mediaScanIntent.setData(contentUri); //设置URI this.sendBroadcast(mediaScanIntent); //发送广播 }把Bitmap保存到外部存储
/** * 把图片保存到SD卡 * @param bitmap * @param targetPath */ public static void SavePhotoToSdCard(Bitmap bitmap, String targetPath) { FileOutputStream fileOutputStream = null; File file = new File(targetPath); try { fileOutputStream = new FileOutputStream(file); if (bitmap != null) { if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)) { fileOutputStream.flush(); } } } catch (FileNotFoundException e) { file.delete(); e.printStackTrace(); } catch (IOException e) { file.delete(); e.printStackTrace(); } finally { try { // 到最后一定要关闭 fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
然后,你就可以在你设备的外部存储根目录下的/Pictures/CameraDemo/目录下面找到你的图片,同时在设备的图库里面发现一个新建项"CameraDemo",里面有拍照或者从图库选择得到的图片。
相关文章推荐
- socket传送自定义对象
- Android开发使用Viewpager实现程序引导界面
- Android事件分发及拦截机制
- Android发版问题总结
- Android HID设备的连接
- 自定义ZXing二维码扫描界面并解决取景框拉伸等问题
- AndroidManifest.xml清单配置文件
- android通讯录之联系人
- Android视图的绘制流程(下)——View的Layout与Draw过程
- Android程序安装后图标不显示
- Android之高德地图定位
- [Android]EventBus-来一趟快速公交初体验[上]
- Android中进程间通信(IPC)方式总结
- Android Studio上方便使用butterknife注解框架的偷懒插件Android Butterknife Zelezny
- AndroidStudio插件GsonFormat快速实现JavaBean
- Android studio 多渠道打包
- Android第三方文件选择器:aFileChooser
- Android第三方文件选择器:aFileChooser
- Android 使用Android Studio + Gradle 或 命令行 进行apk签名打包
- Android drawPath实现QQ拖拽泡泡