Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java로 이미지의 픽셀(RGB 값)을 읽어오는 방법 완벽 정리

디지털 이미지는 2차원 배열 형태의 픽셀(pixel)들로 저장되며, 픽셀은 디지털 이미지를 구성하는 가장 작은 단위입니다.

각 픽셀은 알파(Alpha), 빨강(Red), 초록(Green), 파랑(Blue), 즉 ARGB 값을 담고 있으며, 각 색상 값은 0부터 255 사이의 범위를 가집니다. 이는 하나의 색상 값이 8비트(2^8)를 차지한다는 의미입니다.

ARGB 값은 총 4바이트의 메모리에 일정한 순서(오른쪽에서 왼쪽)로 저장됩니다. 구체적으로 파랑 값은 0~7비트, 초록 값은 8~15비트, 빨강 값은 16~23비트, 알파 값은 24~31비트에 위치합니다.

이미지의 픽셀 정보(ARGB 값) 가져오기

이미지에서 픽셀 값을 읽어오려면 다음 단계를 따릅니다.

  • 이미지의 모든 픽셀을 순회합니다. 즉, 이미지의 높이(height)와 너비(width)를 따라 중첩 루프(nested loop)를 실행합니다.
  • getRGB() 메서드를 사용하여 각 좌표의 픽셀 값을 가져옵니다.
  • 가져온 픽셀 값을 매개변수로 전달하여 Color 객체를 생성합니다.
  • getRed(), getGreen(), getBlue() 메서드를 사용하여 각각 빨강, 초록, 파랑 값을 추출합니다.

예제 코드

다음 Java 예제는 이미지의 모든 픽셀을 읽어 각 픽셀의 RGB 값을 파일에 저장합니다.

import java.io.File;
import java.io.FileWriter;
import java.awt.Color;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

public class GetPixels {
    public static void main(String args[]) throws Exception {
        FileWriter writer = new FileWriter("D:\\Images\\pixel_values.txt");
        // 이미지 읽기
        File file = new File("D:\\Images\\cat.jpg");
        BufferedImage img = ImageIO.read(file);
        for (int y = 0; y < img.getHeight(); y++) {
            for (int x = 0; x < img.getWidth(); x++) {
                // 픽셀 값 가져오기
                int pixel = img.getRGB(x, y);
                // 픽셀 값으로 Color 객체 생성
                Color color = new Color(pixel, true);
                // R, G, B 값 추출
                int red = color.getRed();
                int green = color.getGreen();
                int blue = color.getBlue();
                writer.append(red + ":");
                writer.append(green + ":");
                writer.append(blue + "");
                writer.append("\n");
                writer.flush();
            }
        }
        writer.close();
        System.out.println("각 픽셀의 RGB 값이 지정된 파일에 저장되었습니다.");
    }
}

실행 결과

각 픽셀의 RGB 값이 지정된 파일에 저장되었습니다.

비트 시프트 연산자로 RGB 값 추출하기

Color 객체를 사용하지 않고도 비트 시프트(shift) 연산자를 이용해 픽셀에서 RGB 값을 직접 추출할 수 있습니다.

  • 각 색상 채널의 시작 비트 위치까지 오른쪽으로 시프트합니다. 예를 들어 알파는 24비트, 빨강은 16비트, 초록은 8비트만큼 시프트합니다.
  • 오른쪽 시프트 연산은 다른 채널의 비트까지 함께 이동시킬 수 있으므로, 이를 방지하려면 0xff와 비트 AND(&) 연산을 수행해야 합니다. 이렇게 하면 마지막 8비트만 남기고 나머지 비트는 모두 무시되는 마스크(mask) 효과를 얻을 수 있습니다.
int p = img.getRGB(x, y);
// 픽셀 값에서 A, R, G, B 값 추출
int a = (p >> 24) & 0xff;
int r = (p >> 16) & 0xff;
int g = (p >> 8) & 0xff;
int b = p & 0xff;

이처럼 getRGB() 메서드와 Color 객체를 조합하거나, 비트 연산을 활용하면 이미지의 개별 픽셀 색상 정보를 손쉽게 분석할 수 있습니다. 이미지 처리, 필터 적용, 색상 분석 등 다양한 작업의 기초가 되는 핵심 기법이니 꼭 익혀두시기 바랍니다.