调用摄像头拍照获得图片的步骤
- 点击事件处理调用摄像头逻辑
- 1:创建File对象,用于存放拍摄之后的图片
- 2:存放在SD卡的应用关联缓存之下,为什么?因为6.0以后,读写SD卡被列为危险权限,所以使用应用关联目录则可以跳过这一步
- 3:低于7.0使用Uri的fromFile()方法将File转换为Uri对象,这个Uri对象标识着output_image.jpg图片的本地真实路径。否则,就调用FileProvider的getUriForFile()方法将File对象转换为一个封装过的Uri对象。因为从7.0开始,直接使用本地真是路径的Uri被认为是不安全的,所以要使用FileProvider实际上是一种特殊的ContentProvider,它使用了和ContentProvider类似的机制来对数据进行保护,可以选择性的将封装过的Uri共享给外部,从而提高了应用的安全性。
- 4:构建Intent对象,将action指定为android.media.action.IMAGE_CAPTURE,指定Uri,启动相机Activity
- 5: 通过onActivityResult方法获取jpg并解析为Bitmap对象,设置到ImageView上即可
- 6:添加判断图片旋转的方法,自动转屏
private val takePhoto = 1
lateinit var imageUri: Uri
lateinit var outputImage: File
cameraButton.setOnClickListener {
outputImage = File(externalCacheDir, "output_image.jpg")
if (outputImage.exists()) {
outputImage.delete()
}
outputImage.createNewFile()
imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
FileProvider.getUriForFile(this, "com.example.camera.test", outputImage)
} else {
Uri.fromFile(outputImage)
}
val intent = Intent("android.media.action.IMAGE_CAPTURE")
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
startActivityForResult(intent, takePhoto)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
takePhoto -> {
if (resultCode == Activity.RESULT_OK) {
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
mImageView.setImageBitmap(rotateIfRequired(bitmap))
}
}
}
}
private fun rotateIfRequired(bitmap: Bitmap): Bitmap {
val exif = ExifInterface(outputImage.path)
val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL)
return when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> rotateBitmap(bitmap, 90)
ExifInterface.ORIENTATION_ROTATE_180 -> rotateBitmap(bitmap, 180)
ExifInterface.ORIENTATION_ROTATE_270 -> rotateBitmap(bitmap, 270)
else -> bitmap
}
}
private fun rotateBitmap(bitmap: Bitmap, degree: Int): Bitmap {
val matrix = Matrix()
matrix.postRotate(degree.toFloat())
val rotateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
bitmap.recycle()
return rotateBitmap
}
调用相册获取图片的步骤
- 1:实现点击方法
- 2:打开文件选择器
- 3:指定只显示图片
- 4:调起
- 5:回调方法中获取uri
albumButton.setOnClickListener {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"
startActivityForResult(intent, fromAlbum)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
takePhoto -> {
if (resultCode == Activity.RESULT_OK) {
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
mImageView.setImageBitmap(rotateIfRequired(bitmap))
}
}
fromAlbum -> {
if (resultCode == Activity.RESULT_OK && data != null) {
data.data?.let { uri ->
val bitmap = getBitmapFromUri(uri)
mImageView.setImageBitmap(bitmap)
}
}
}
}
}
private fun getBitmapFromUri(uri: Uri) = contentResolver
.openFileDescriptor(uri, "r")?.use {
BitmapFactory.decodeFileDescriptor(it.fileDescriptor)
}