[안드로이드] Glide 라이브러리를 이용한 갤러리에서 이미지 불러오기

동현·2020년 10월 11일
0
post-thumbnail
post-custom-banner

Glide는 빠르고 효율적인 안드로이드용 오픈소스 미디어 관리 및 이미지 로딩 프레임워크이다. 어플을 만드는 도중, 갤러리의 이미지를 원 또는 모서리가 둥근 이미지로 이미지뷰에 불러오고 싶은 적이 있었는데, 이때 유용하게 썼던 라이브러리가 Glide이다.

1. Gradle 추가

app 수준의 build.gradle에 가서 다음과 같은 내용을 추가해주자.

implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

여기에서 최신 버전을 확인할 수 있다. 최신 버전을 쓰고 싶은 경우, 위에 4.11.0 대신 최신 버전을 적으면 된다.

2. ImageView 추가

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginLeft="16dp"
            android:layout_weight="0"
            app:srcCompat="@android:drawable/ic_menu_gallery" />

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_weight="0"
            app:srcCompat="@android:drawable/ic_menu_gallery" />

        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginRight="16dp"
            android:layout_weight="0"
            app:srcCompat="@android:drawable/ic_menu_gallery" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

갤러리에서 이미지를 불러와 표시해줄 이미지뷰를 추가해주자. 여러 예제를 실험해볼 것이기에 이미지뷰를 3개 추가해주었다.

3. 이미지뷰에 OnClickListener 추가

imageView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, GET_IMAGE_FOR_IMAGEVIEW1);
            }
        });
        imageView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, GET_IMAGE_FOR_IMAGEVIEW2);
            }
        });
        imageView3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, GET_IMAGE_FOR_IMAGEVIEW3);
            }
        });

이미지뷰에 OnClickListener를 추가해 눌렀을 때, 갤러리에서 사진을 선택할 수 있도록 하였다. startActivityForResult() 메소드를 쓰게 되면 두번째 인자에 보통 정수형 인자를 하나 주게 되는데, 이 정수형 인자에 따라 onActivityResult() 메소드에서 다른 작업을 처리할 수 있게 할 수 있다.

private final int GET_IMAGE_FOR_IMAGEVIEW1 = 201;
private final int GET_IMAGE_FOR_IMAGEVIEW2 = 202;
private final int GET_IMAGE_FOR_IMAGEVIEW3 = 203;

따라서 이런식으로 각 이미지뷰마다 다른 정수형 인자를 주도록 하였다.

3. onAcitivtyResult() 메소드 작성

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Uri selectedImageUri;
    RequestOptions option1 = new RequestOptions().circleCrop();
    MultiTransformation option2 = new MultiTransformation(new CenterCrop(), new RoundedCorners(8));
    MultiTransformation option3 = new MultiTransformation(new FitCenter(), new RoundedCorners(30));

    super.onActivityResult(requestCode, resultCode, data);
        
    if (resultCode == RESULT_OK && data != null && data.getData() != null) {
        switch(requestCode) {
            case GET_IMAGE_FOR_IMAGEVIEW1:
                selectedImageUri = data.getData();
                Glide.with(getApplicationContext()).load(selectedImageUri).apply(option1).into(imageView1);
                break;
            case GET_IMAGE_FOR_IMAGEVIEW2:
                selectedImageUri = data.getData();
                Glide.with(getApplicationContext()).load(selectedImageUri).apply(RequestOptions.bitmapTransform(option2)).into(imageView2);
                break;
            case GET_IMAGE_FOR_IMAGEVIEW3:
                selectedImageUri = data.getData();
                Glide.with(getApplicationContext()).load(selectedImageUri).apply(RequestOptions.bitmapTransform(option3)).into(imageView3);
                break;
         }
    }
}

다음과 같이 startActivityForResult() 메소드에서 전달받은 requestCode에 따라 다른 작업을 하도록 할 수 있다.

RequestOptions option1 = new RequestOptions().circleCrop();

Glide.with(getApplicationContext()).load(selectedImageUri).apply(option1).into(imageView1);

하나의 변형만 줄 경우 다음과 같이 사용할 수 있으며,

MultiTransformation option2 = new MultiTransformation(new CenterCrop(), new RoundedCorners(8));
Glide.with(getApplicationContext()).load(selectedImageUri).apply(RequestOptions.bitmapTransform(option2)).into(imageView2);

여러 변형을 줄 경우 다음과 같이 MultiTransformation을 이용해 순서대로 적용되게 할 수 있다. 물론 이외에도 다양한 변형을 줄 수 있으니 자세한 건 공식 문서를 참고하면 된다.

package com.example.sampleglide;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.MultiTransformation;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.FitCenter;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;

public class MainActivity extends AppCompatActivity {
    private ImageView imageView1;
    private ImageView imageView2;
    private ImageView imageView3;

    private final int GET_IMAGE_FOR_IMAGEVIEW1 = 201;
    private final int GET_IMAGE_FOR_IMAGEVIEW2 = 202;
    private final int GET_IMAGE_FOR_IMAGEVIEW3 = 203;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView1 = findViewById(R.id.imageView1);
        imageView2 = findViewById(R.id.imageView2);
        imageView3 = findViewById(R.id.imageView3);

        imageView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, GET_IMAGE_FOR_IMAGEVIEW1);
            }
        });
        imageView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, GET_IMAGE_FOR_IMAGEVIEW2);
            }
        });
        imageView3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, GET_IMAGE_FOR_IMAGEVIEW3);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Uri selectedImageUri;
        RequestOptions option1 = new RequestOptions().circleCrop();
        MultiTransformation option2 = new MultiTransformation(new CenterCrop(), new RoundedCorners(8));
        MultiTransformation option3 = new MultiTransformation(new FitCenter(), new RoundedCorners(30));

        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && data != null && data.getData() != null) {
            switch(requestCode) {
                case GET_IMAGE_FOR_IMAGEVIEW1:
                    selectedImageUri = data.getData();
                    Glide.with(getApplicationContext()).load(selectedImageUri).apply(option1).into(imageView1);
                    break;
                case GET_IMAGE_FOR_IMAGEVIEW2:
                    selectedImageUri = data.getData();
                    Glide.with(getApplicationContext()).load(selectedImageUri).apply(RequestOptions.bitmapTransform(option2)).into(imageView2);
                    break;
                case GET_IMAGE_FOR_IMAGEVIEW3:
                    selectedImageUri = data.getData();
                    Glide.with(getApplicationContext()).load(selectedImageUri).apply(RequestOptions.bitmapTransform(option3)).into(imageView3);
                    break;
            }
        }
    }
}

전체 코드는 다음과 같다.

4. 실행 결과

사용된 이미지의 경우 600×400 픽셀이다.

5. 참조

"Glide v4", https://bumptech.github.io/glide/

profile
https://github.com/DongChyeon
post-custom-banner

0개의 댓글