HOWTO · Java
Java에서 이미지 자르기
이 기사에서는 Java에서 이미지를 자르는 방법에 대해 설명하고 이를 위해 BufferedImage 클래스의 subimage 함수를 사용하여 Java에서 이미지를 자릅니다.
이 페이지의 내용
Java에서는 BufferedImage.getSubimage(x, y, width, height)를 사용해 이미지의 직사각형 영역을 자른 다음, 반환된 이미지를 ImageIO로 저장할 수 있습니다. 자를 영역은 왼쪽 위 좌표 (x, y)에서 시작하며, 너비와 높이로 원본에서 남길 범위를 정합니다.
BufferedImage.getSubimage로 이미지 자르기
BufferedImage는 픽셀에 메모리에서 접근할 수 있는 이미지를 나타냅니다. getSubimage 메서드는 해당 이미지에서 직사각형 영역을 나타내는 뷰를 반환합니다. 인수는 직사각형의 왼쪽 위 좌표인 x와 y, 그리고 width와 height 순서입니다. 반환된 이미지는 요청한 크기를 가지며 픽셀 데이터를 원본과 공유합니다. 이후 원본이나 잘린 이미지를 서로 독립적으로 수정해야 한다면 복사본을 사용하세요.
이미지 읽기 및 자른 결과 저장
프로그램의 인수 두 개로 입력 이미지 경로와 .png로 끝나는 출력 경로를 지정하세요. 인수를 전달하지 않으면 예제에서 임시 디렉터리에 작은 샘플 PNG를 만들어 다른 파일 없이도 전체 흐름을 보여 줍니다. 선택한 입력 이미지를 ImageIO로 읽고, 영역을 자른 다음 PNG로 저장합니다. 이미지에 맞게 자르기 좌표를 변경하세요.
다음은 단독으로 실행할 수 있는 예제입니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.imageio.ImageIO;
public class Main {
public static void main(String[] args) {
try {
Path inputPath;
Path outputPath;
if (args.length == 2) {
inputPath = Paths.get(args[0]);
outputPath = Paths.get(args[1]);
} else if (args.length == 0) {
Path folder = Files.createTempDirectory("java-crop-");
inputPath = folder.resolve("source.png");
outputPath = folder.resolve("crop.png");
BufferedImage sample = new BufferedImage(100, 80, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < sample.getHeight(); y++) {
for (int x = 0; x < sample.getWidth(); x++) {
sample.setRGB(x, y, (x < 50) ? Color.BLUE.getRGB() : Color.ORANGE.getRGB());
}
}
ImageIO.write(sample, "png", inputPath.toFile());
} else {
System.out.println("Provide both an input path and an output path.");
return;
}
if (!outputPath.getFileName().toString().toLowerCase().endsWith(".png")) {
System.out.println("The output path must end in .png.");
return;
}
BufferedImage source = ImageIO.read(inputPath.toFile());
if (source == null) {
System.out.println("The input format is not supported.");
return;
}
int x = 20;
int y = 15;
int width = 40;
int height = 30;
if (x < 0 || y < 0 || width <= 0 || height <= 0
|| x > source.getWidth() - width || y > source.getHeight() - height) {
System.out.println("The crop rectangle must fit inside the input image.");
return;
}
BufferedImage crop = source.getSubimage(x, y, width, height);
boolean written = ImageIO.write(crop, "png", outputPath.toFile());
if (written) {
System.out.println("Saved crop: " + crop.getWidth() + "x" + crop.getHeight());
} else {
System.out.println("No PNG writer is available.");
}
} catch (IOException ex) {
System.out.println("Image file operation failed: " + ex.getMessage());
}
}
}
Saved crop: 40x30
선택한 원본 이미지와 자른 결과를 나란히 볼 수 있습니다. 제공된 이미지는 실제 이미지에서 영역을 잘랐을 때의 시각적 변화를 보여 줍니다.
| 자르기 전 | 자르기 후 |
|---|---|
|
|
자르기 좌표와 크기 선택
좌표는 원본 이미지의 왼쪽 위 모서리에서 시작합니다. x는 오른쪽으로 갈수록 커지고 y는 아래쪽으로 갈수록 커집니다. 예제에서 (20, 15)는 자를 영역의 시작점이며, 40과 30은 영역의 너비와 높이입니다. 너비가 W, 높이가 H인 이미지에서는 x와 y를 0 이상으로, 너비와 높이를 양수로 지정하고 x + width <= W와 y + height <= H를 만족해야 합니다. 예를 들어 x = 20에서 시작해 너비가 40픽셀인 영역은 59번째 열에서 끝나므로, 원본 이미지의 너비는 최소 60픽셀이어야 합니다.
잘못된 입력과 일반적인 오류 처리
ImageIO.read(File)는 파일을 읽을 수 없을 때 IOException을 던질 수 있습니다. 등록된 리더가 입력 형식을 인식하지 못하면 null을 반환할 수도 있으므로, getSubimage를 호출하기 전에 반환값을 확인하세요. 예제는 파일 작업 오류를 처리하고 PNG 작성기를 사용할 수 있는지 확인합니다. ImageIO.write(RenderedImage, String, File)는 요청한 형식으로 쓸 수 없으면 false를 반환합니다.
원본 이미지의 경계를 벗어난 자르기 영역이나 너비 또는 높이가 0 이하인 영역을 지정하면 getSubimage가 RasterFormatException을 던집니다. 자세한 내용은 BufferedImage.getSubimage API 문서를 참조하세요. 특히 좌표를 사용자 입력에서 가져온다면 메서드를 호출하기 전에 크기를 검증하세요. 예제를 실행할 때는 쓸 수 있는 출력 위치를 지정하고 PNG 형식 이름과 .png 파일 확장자를 일치시키세요.