Image Crop 후 Image View에 뿌려주기

장똑대·2021년 6월 23일
private fun selectPhoto() {
        val photoPickerIntent = Intent(Intent.ACTION_PICK)
        photoPickerIntent.type = MediaStore.Images.Media.CONTENT_TYPE

        startForSelectPhotoResult.launch(photoPickerIntent)
    }

    private val startForSelectPhotoResult: ActivityResultLauncher<Intent> =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
            if (result.resultCode == RESULT_OK) {
                cropImage(result.data?.data)
            }
        }

🔼 참고 포스트에서 사용되었던 onActivityResult(), startActivityForResult()는 deprecated 되어 ActivityResult API를 사용


private fun cropImage(photoDirectory: Uri?) {
        var photoUri: Uri? = photoDirectory

        val intent = Intent("com.android.camera.action.CROP")
        intent.setDataAndType(photoUri, "image/*")

        val list: MutableList<ResolveInfo> = packageManager.queryIntentActivities(intent, 0)
        val getCropImageActivity: ResolveInfo = list.get(0)

        grantUriPermission(
            getCropImageActivity.activityInfo.packageName,
            photoUri,
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
        )

        if (list.size == 0) {
            Toast.makeText(this, "Canceled", Toast.LENGTH_SHORT).show()
            return
        } else {
            intent.putExtra("crop", "true")
            intent.putExtra("aspectX", 1)
            intent.putExtra("aspectY", 1)
            intent.putExtra("scale", true)

            val storageDirectory: Array<File> =
                ContextCompat.getExternalFilesDirs(applicationContext, null)

            val croppedFileName: File = File.createTempFile(
                "임의지정_${SimpleDateFormat("HHmmss").format(Date())}_",
                ".jpg",
                storageDirectory[0]
            )

            val folder: Array<File> =
                ContextCompat.getExternalFilesDirs(applicationContext, null)
            val tempFile: File = File(folder[0].toString(), croppedFileName.name)
            photoUri = FileProvider.getUriForFile(
                this,
                "패키지명.provider",
                tempFile
            )
            intent.putExtra("return-data", false)
            intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString())

            val cropIamgeIntent = Intent(intent)
            cropIamgeIntent.component = ComponentName(
                getCropImageActivity.activityInfo.packageName,
                getCropImageActivity.activityInfo.name
            )

            grantUriPermission(
                getCropImageActivity.activityInfo.packageName, photoUri,
                Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
            )

            startForCropImageResult.launch(cropIamgeIntent)
        }
    }
    private val startForCropImageResult: ActivityResultLauncher<Intent> =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
            when (result.resultCode) {
                RESULT_OK -> {
                    Glide.with(this).load(result.data?.data)
                        .circleCrop().error(R.drawable.sample).into(binding.ivProfileEditPhoto)
                }

                RESULT_CANCELED -> {
                    Glide.with(this)
                        .load(변경 전 이미지 uri)
                        .circleCrop().error(R.drawable.sample).into(binding.ivProfileEditPhoto)
                }
            }
        }
  • FileProvider : 콘텐츠를 다른 앱으로 안전하게 전달하기 위해 URI로 전달
  • getExternalStorageDirectory() 는 deprecated되어 getExternalFilesDirs()로 대체


  • 외부 저장소는 내부 메모리의 파티션을 외부 저장소로 할당 / SD카드 장착 두가지의 경우로 나뉜다. 이런 이유로 실제 외부 저장소 볼륨은 여러가지가 있는데, 내부 메모리의 파티션에서 할당된 외부 저장소(기본 외부 저장소)는 배열의 첫번째에 반환되기때문에 storageDir[0]을 사용







참고 포스트 : programmar.tistory.com/5

profile
장똑대와 안드로이드

0개의 댓글