관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] 갤러리 사진 불러오는 방법(다중선택 포함) + Crop 기능 본문

안드로이드/자바 & Previous

[안드로이드] 갤러리 사진 불러오는 방법(다중선택 포함) + Crop 기능

막무가내막내 2019. 4. 26. 20:13
728x90

 

 

이번에는 안드로이드폰의 갤러리 저장소에 접근해서 갤러리 사진을 불러오는 방법에 대해 포스팅한다.

 

방법은 다음 예제를 보면 간단하다. (난 circle이미지뷰를 클릭하고 여기에 이미지를 세팅하는 예시를 들었다. )

 

먼저 onCreate()에 다음과 같이 클릭이벤트를 작성한다.

 //프로필이미지 클릭 시
        mPhotoCircleImageView.setOnClickListener(new View.OnClickListener() {
            @Override //이미지 불러오기기(갤러리 접근)
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(intent, PICK_IMAGE); //PICK_IMAGE에는 본인이 원하는 상수넣으면된다.
            }
        });

위에 코드는 갤러리에 접근하는 코드인데 저렇게 하면 위에 스마트폰 에뮬레이터처럼 구글갤러리로 접근한다.

만약 기본 갤러리로 접근하게 하고싶으면 위에 코드 대신 다음과 같이 Intent를 해주면된다.

Intent intent = new Intent(Intent.ACTION_PICK);
                            intent.setType
                                    (android.provider.MediaStore.Images.Media.CONTENT_TYPE);
                            startActivityForResult(intent, RequestCode.PICK_IMAGE);

 

 

그리고 해당 액티비티에 onResultActivity()를 오버라이딩해서 다음과 같이 받아온 사진을 비트맵으로 변환하고 뷰에 세팅해주면 끝난다.

@Override //갤러리에서 이미지 불러온 후 행동
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Check which request we're responding to
        if (requestCode == PICK_IMAGE) {
            // Make sure the request was successful
            if (resultCode == RESULT_OK) {
                try {
                    // 선택한 이미지에서 비트맵 생성
                    InputStream in = getContentResolver().openInputStream(data.getData());
                    Bitmap img = BitmapFactory.decodeStream(in);
                    in.close();
                    // 이미지뷰에 세팅
                    mPhotoCircleImageView.setImageBitmap(img);
                  
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

 

 

 

 

 

 

 

[여기서부터는 CROP 기능입니다.] 추가로 이 코드는 위 코드 처럼 구글 디렉토리로 접근을 안하고 갤러리로 접근합니다.

//crop 라이브러리를 gradle에 추가해주세요
implementation 'com.github.yalantis:ucrop:2.2.3'

예제코드를 기록해놨으며 어렵지 않게 참고할 수 있으실겁니다.

package com.mtjin.visionapp

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import com.yalantis.ucrop.UCrop
import java.io.File


class GalleryActivity : AppCompatActivity() {
    private lateinit var imageView: ImageView
    private lateinit var loadImageButton: Button
    private lateinit var indicateButton: Button
    private lateinit var sendButton: Button
    private lateinit var imageUri: Uri


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_gallery)
        initView()
        initListener()
    }

    private fun initListener() {
        loadImageButton.setOnClickListener {
            val intent = Intent(Intent.ACTION_PICK)
            intent.type = MediaStore.Images.Media.CONTENT_TYPE
            intent.type = "image/*"
            startActivityForResult(
                intent,
                PICK_IMAGE
            )
        }
    }

    private fun initView() {
        imageView = findViewById(R.id.gallery_iv_image)
        loadImageButton = findViewById(R.id.gallery_btn_load)
        indicateButton = findViewById(R.id.gallery_btn_indicate)
        sendButton = findViewById(R.id.gallery_btn_send)
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK) {
            if (requestCode == PICK_IMAGE) {
                val sourceUri = data!!.data
                if (sourceUri != null) {
                    val destinationUri = Uri.fromFile(File(cacheDir, "cropped"))
                    openCropActivity(sourceUri, destinationUri)
                } else {
                    Toast.makeText(this, getString(R.string.get_img_error_msg), Toast.LENGTH_SHORT).show()
                }
            } else if (requestCode == UCrop.REQUEST_CROP) {
                val resultUri = UCrop.getOutput(data!!)
                if (resultUri != null) {
                    Log.d("AAA","AAa")
                    //초기화
                    imageView.setImageDrawable(null)
                    //이미지뷰에 세팅
                    imageUri = resultUri
                    imageView.setImageURI(imageUri)
                    //Glide.with(this).load(imageUri).fitCenter().into(imageView)
                } else {
                    Toast.makeText(this, getString(R.string.get_img_error_msg), Toast.LENGTH_SHORT).show()
                }
            }
        } else if (resultCode == UCrop.RESULT_ERROR) {
            Toast.makeText(this, getString(R.string.get_img_error_msg), Toast.LENGTH_SHORT).show()
        }
    }

    private fun openCropActivity(
        sourceUri: Uri,
        destinationUri: Uri
    ) {
        UCrop.of(sourceUri, destinationUri)
            .start(this)
    }

    companion object {
        const val PICK_IMAGE = 1
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="10"
    android:background="@drawable/bg_main_gradient"
    tools:context=".GalleryActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9">
    <ImageView
        android:id="@+id/gallery_iv_image"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <Button
            android:id="@+id/gallery_btn_load"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/colorBlue"
            android:text="갤러리에서 가져오기"
            android:textColor="@color/colorWhite"
            app:layout_constraintEnd_toStartOf="@+id/gallery_btn_indicate"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/gallery_iv_image" />

        <Button
            android:id="@+id/gallery_btn_indicate"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/colorRed"
            android:text="강조할부분 터치"
            android:textColor="@color/colorWhite"
            app:layout_constraintLeft_toRightOf="@id/gallery_btn_load"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/gallery_iv_image" />

        <Button
            android:id="@+id/gallery_btn_send"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/colorBlue"
            android:text="전송"
            android:textColor="@color/colorWhite"
            app:layout_constraintLeft_toRightOf="@id/gallery_btn_load"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/gallery_iv_image" />
    </LinearLayout>


</LinearLayout>

 

 

 


 

[2021-01-08 추가]

이미지 다중 선택 

 

권한 추가

   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

 

사진 선택시키기

showToast("길게 누르면 다중 사진선택이 가능합니다. (최대 9장)")
                val intent = Intent()
                intent.type = "image/*"
                intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
                intent.action = Intent.ACTION_GET_CONTENT
                startActivityForResult(
                    Intent.createChooser(intent, "사진 최대 9장 선택가능"),
                    RC_PICK_IMAGE
                )

 

사진 선택 결과 처리

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK && requestCode == RC_PICK_IMAGE) {
            if (data?.clipData != null) { // 사진 여러개 선택한 경우
                val count = data.clipData!!.itemCount
                if (count > 9) {
                    showToast(getString(R.string.max_image_select_msg))
                    return
                }
                viewModel.imageUriList.clear()
                for (i in 0 until count) {
                    val imageUri = data.clipData!!.getItemAt(i).uri
                    viewModel.imageUriList.add(imageUri)
                }
                binding.ivImage.setImageURI(data.clipData!!.getItemAt(0).uri)
                if (count > 1) {
                    binding.tvImageCount.visibility = View.VISIBLE
                    binding.tvImageCount.text = "외 " + (count - 1) + "장"
                } else {
                    binding.tvImageCount.visibility = View.GONE
                }
            } else { // 단일 선택
                data?.data?.let { uri ->
                    viewModel.imageUriList.clear()
                    viewModel.imageUriList.add(uri)
                    binding.ivImage.setImageURI(uri)
                    binding.tvImageCount.visibility = View.GONE
                }
            }
        }
    }

 

 

 

댓글과 공감은 큰 힘이됩니다. !

 

728x90
Comments