본문 바로가기
안드로이드 자바

[JAVA][Android] Palette를 사용하여 이미지, 사진 색상 정보 추출하기

by teamnova 2024. 10. 23.
728x90

Palette 라이브러리는 안드로이드 앱에서 이미지 색상 정보를 추출하고 이를 UI에 적용하는데 유용합니다.

 

1. Palttle 라이브러리를 사용 이유

 

 색상추출 : 이미지에서 주도적인 색상, 어두운 색상, 밝은 색상 등을 추출하여 UI요소에 적용 할 수 있습니다.

 시각적 일관성 : 앱의 UI 디자인에서 색상 조화를 유지하여 사용자에게 일관된 느낌을 제공합니다.

 자동색상: 개발자가 수동으로 색상을 선택 할 필요가 없어, 이미지에 따라 자동으로 색상을 조정 할 수 있습니다.

 

2. 앱에 적용하면 좋은 사례

 

 이미지 갤러리 앱 :  갤러리 앱에서 사용자가 선택한 이미지의 색상에 따라 제목이나 설명, 텍스트의 배경색을 조정하여 더 나은

                               가독성을 제공 할 수 있습니다.

 

 소셜 미디어 플랫폼 : 사용자가 프로필 배경색을 업로드 이미지 색상에 맞추어 자동으로 변화하게 하여 개인화된 
                                 경험을 제공합니다.

 

 쇼핑 앱 : 이미지의 주 색상을 기반으로 관련 상품의 UI 색상을 자동으로 조정하여 사용자에게 더 나은 쇼핑 경험을 제공합니다.

 

 디자인 도구 앱 : 사용자에게 선택된 이미지의 색상 조합을 추출하고 이를 사용하여 색상 팔레트를 생성 할 수 있는 기능을

                          제공하여 디자인 작업을 돕습니다.

 

activity_main.xml
<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">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="300dp"
        android:scaleType="centerCrop"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/textView"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:textSize="24sp"
        app:layout_constraintTop_toBottomOf="@id/imageView"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <Button
        android:id="@+id/search_img_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="24dp"
        android:layout_marginBottom="280dp"
        android:text="검색하기"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <EditText
        android:id="@+id/search_img"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginBottom="280dp"
        android:hint="이미지 주소를 입력하세요"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/search_img_btn"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity

import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.palette.graphics.Palette;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;

import org.jetbrains.annotations.Nullable;

public class MainActivity extends AppCompatActivity {

    ImageView imageView;
    TextView textView;
    Button button;
    EditText editText;

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

        imageView = findViewById(R.id.imageView);
        textView = findViewById(R.id.textView);
        button = findViewById(R.id.search_img_btn);
        editText = findViewById(R.id.search_img);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String imgUrl = editText.getText().toString().trim();
                if (!imgUrl.isEmpty()) {
                    // 이미지 로드 (Glide 사용)
                    Glide.with(MainActivity.this)
                            .asBitmap() // 비트맵으로 로드
                            .load(imgUrl) // 여기에 이미지 URL을 추가하세요
                            .into(new CustomTarget<Bitmap>() {
                                @Override
                                public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                                    imageView.setImageBitmap(resource); // 이미지 뷰에 비트맵 설정
                                    generatePalette(resource); // 팔레트 생성
                                }

                                @Override
                                public void onLoadCleared(@Nullable Drawable placeholder) {
                                    // 이미지 로드가 취소되었을 때의 동작 (필요시 구현)
                                }
                            });
                } else {
                    textView.setText("이미지 주소를 입력해 주세요!");
                }
            }
        });
    }

    private void generatePalette(Bitmap bitmap) {
        Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(@NonNull Palette palette) {
                // 색상 추출
                int vibrantColor = palette.getVibrantColor(0);
                int darkVibrantColor = palette.getDarkVibrantColor(0);
                int lightVibrantColor = palette.getLightVibrantColor(0);

                // UI 요소에 색상 적용
                textView.setBackgroundColor(vibrantColor);
                textView.setText("Vibrant Color: #" + Integer.toHexString(vibrantColor).toUpperCase());
            }
        });
    }
}

 

 

implementation 'com.github.bumptech.glide:glide:4.13.2' // Glide 라이브러리
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.2'
implementation 'androidx.palette:palette:1.0.0' // Palette 라이브러리

 

 

인터넷 이미지 예시 주소:

https://src.hidoc.co.kr/image/lib/2024/2/2/1706870132971_0.jpg

 

시연 영상