세피아(Sepia) 효과는 사진에 따뜻하고 빈티지한 갈색빛 감성을 더하는 대표적인 이미지 필터입니다. 이 글에서는 Java의 BufferedImage와 Color 클래스를 활용해 컬러 이미지를 세피아 이미지로 변환하는 알고리즘과 전체 구현 코드를 단계별로 살펴보겠습니다.
세피아 변환 알고리즘
컬러 이미지를 세피아 톤으로 바꾸는 핵심 원리는 다음과 같습니다.
이미지의 각 픽셀에서 빨강(Red), 초록(Green), 파랑(Blue) 값을 추출합니다.
세 색상 값의 평균값을 계산합니다.
깊이(depth)와 강도(intensity) 값을 정의합니다. 일반적으로 20과 30이 적절합니다.
다음 규칙에 따라 각 색상 값을 조정합니다.
red = red + (depth × 2)
green = green + depth
blue = blue − intensity
조정된 값이 반드시 0~255 범위 안에 있도록 보정합니다.
수정된 RGB 값으로 새로운 픽셀을 만들어 원래 위치에 설정합니다.
Java 구현 절차
ImageIO.read()메서드로 대상 이미지를 읽어옵니다.이미지의 높이(height)와 너비(width)를 구합니다.
중첩 for 루프를 사용해 이미지의 모든 픽셀을 순회합니다.
getRGB()메서드로 픽셀 값을 가져옵니다.가져온 픽셀 값을 매개변수로 전달하여
Color객체를 생성합니다.getRed(),getGreen(),getBlue()메서드로 각각 R, G, B 값을 추출합니다.알고리즘에 명시된 공식대로 새로운 R, G, B 값을 계산합니다.
수정된 RGB 값으로 새로운 픽셀을 생성합니다.
setRGB()메서드로 새 픽셀 값을 이미지에 적용합니다.
전체 예제 코드
import java.io.File;
import java.io.IOException;
import java.awt.Color;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class Color2Sepia {
public static void main(String args[]) throws IOException {
// 이미지 읽기
File file = new File("D:\\Images\\cuba.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();
int avg = (red + green + blue) / 3;
int depth = 20;
int intensity = 30;
red = avg + (depth * 2);
green = avg + depth;
blue = avg - intensity;
// RGB 값이 0~255 범위를 벗어나지 않도록 보정
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
if (blue < 0) blue = 0;
// 새로운 Color 객체 생성
color = new Color(red, green, blue);
// 수정된 색상을 이미지에 적용
img.setRGB(x, y, color.getRGB());
}
}
// 수정된 이미지 저장
file = new File("D:\\Images\\sepia_image2.jpg");
ImageIO.write(img, "jpg", file);
System.out.println("Done...");
}
}실행 결과
위 코드를 실행하면 입력된 컬러 이미지의 모든 픽셀이 순차적으로 처리되어, 따뜻한 갈색 계열의 세피아 톤 이미지로 변환됩니다. 최종 결과물은 지정한 경로에 JPG 파일로 저장되며, 콘솔에는 "Done..." 메시지가 출력됩니다.
참고 사항
new Color(pixel, true)에서 두 번째 인자true는 알파(투명도) 채널을 포함한다는 의미입니다. PNG처럼 투명도가 있는 이미지도 안전하게 처리할 수 있습니다.depth와 intensity 값을 조절하면 세피아 효과의 강약을 자유롭게 변경할 수 있습니다.
대용량 이미지를 처리할 경우 픽셀 단위 순회 방식은 시간이 다소 걸릴 수 있으므로, 성능이 중요하다면
Raster나WritableRaster를 활용한 배치 처리를 고려해 보세요.