이미지 리사이징 및 기타 가공처리.(Java)

2024. 3. 20. 18:12개발

반응형

 

대부분의 회사에서 고객사를 늘리면서 회사 홈페이지에 계약체결에 대한 자랑(?)을 하기 위해  고객사들을 나열하거나 하는 경우가 많다...

기존에는 회사 홈페이지에 고객사를 이미지를 추가 할 때 별도로 포토샵같은 걸로 수동작업(디자이너분이 현재는 퇴사하셨다.) 하는 부분이 있었다.(해당 회사로부터 받은 로고가 아닌 임의로 추출 및 이미지 사이즈등이 안맞는 이슈가 있다.)

그리고 위에서도 말했다싶이 디자이너분이 나간상태라 다른 회사동료 개발자가 대략 몇십~ 몇백장의 이미지를 포토샵으로 동일하게 처리해야하나 고민하는 모습을 보고 간단하게라도 도움을 주고자 코드로 만들어보았다.

 

분석.

예를들면 다음과 같이 크기가 큰데 비율이 안맞는 로고가 있다.(해당파일의 크기는 750x579로 이미지가 크기도 하며 회사에서 원하는 위치에 원하는 비율로 그려진게 아님.)

해당 로고를 비율을 맞춰서 다음과 같이 변경해줘야한다.

실질적으로 로고가 정의되는 크기는 대략 가로 250에 세로 150정도로 잡힌다고 한다.

이미지가 큰 경우 해당 이미지를 동일한 비율로 유지하여 250x150의 크기의 가운데에 위치하도록 그려주는 형태로 하면된다.

 

실질적으로 다음과 같은 코드로 생성했다.

@Slf4j
public class ResizeTest {

    @Test
    @DisplayName("이미지 단건 리사이징 테스트")
    void imageResizeOneTest() throws IOException {
        // 배경 크기
        int backgroundWidth = 250;
        int backgroundHeight = 150;
        BufferedImage background = drawBackgroundImage(backgroundWidth, backgroundHeight, new Color(51, 51, 51)); // rgb 888888값

        // 이미지 파일 경로
        final String inputImagePath = "파일경로/part1_62.png";

        // 배경 이미지에 그리기
        File file = new File(inputImagePath);

        // 2분의1 크기로 생성
        int newWidth = Math.round((float) backgroundWidth / 2);
        int newHeight = Math.round((float) backgroundHeight / 2);
        drawOriginImage(backgroundWidth, backgroundHeight, newWidth, newHeight, background, file);

    }

    @Test
    @DisplayName("이미지 여러건 리사이징 테스트")
    void imageResizeListTest() throws IOException {

        final String folderPath = "파일경로";
        File folder = new File(folderPath);
        File[] files = folder.listFiles();

        assert files != null;
        for (File file : files) {

                // 배경 크기
                int backgroundWidth = 250;
                int backgroundHeight = 150;

                //배경 이미지 그리기
                BufferedImage background = drawBackgroundImage(backgroundWidth, backgroundHeight, null);

                // 2분의1 크기로 생성
                int newWidth = Math.round((float) backgroundWidth / 2);
                int newHeight = Math.round((float) backgroundHeight / 2);

                //기존 이미지 그리기
                drawOriginImage(backgroundWidth, backgroundHeight, newWidth, newHeight, background, file);
        }

    }

    private BufferedImage drawBackgroundImage(int backgroundWidth, int backgroundHeight, Color color) {
        // 배경 이미지 생성
        BufferedImage background = new BufferedImage(backgroundWidth, backgroundHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D gBackground = background.createGraphics();
        if (color != null) {
            gBackground.setColor(color);
        }

        gBackground.fillRect(0, 0, backgroundWidth, backgroundHeight);
        gBackground.dispose();

        return background;
    }

    private void drawOriginImage(int backgroundWidth, int backgroundHeight, int newWidth, int newHeight, BufferedImage background, File file) throws IOException {
        //기본정보
        String fileName = file.getName().split("\\.")[0];
        BufferedImage image = ImageIO.read(file);

        // 중앙 좌표 계산
        int x = (backgroundWidth - newWidth) / 2;
        int y = (backgroundHeight - newHeight) / 2;

        // 배경 이미지에 이미지 B 그리기
        Graphics2D g = background.createGraphics();
        g.drawImage(image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), x, y, null);
        g.dispose();

        // 결과 이미지 저장
        String outputImagePath = "파일경로"+fileName+"_result.png";
        ImageIO.write(background, "png", new File(outputImagePath));
        log.info("이미지가 배경의 정확한 중앙에 그려졌습니다. 대상 file : {}", fileName);
    }

}

 

 

위 코드대로 수행하게되면 다음과 같이 처리하게된다.

1번
배경으로 250x150의 범위를 가지는 이미지를 그린다.

2번
파일을 불러와서 해당 파일을 배경의 2분의1 크기로 스케일을 조절하여 그려넣는다.

3번
해당파일을 원하는 위치에 저장한다.

 

나에게 주어진 일은 아니였지만...

오랜만에 여러가지 생각하면서 코드를 짜면서 확인하니 나름의 재미가 있었다. (실질적인 쓰임이 생기고 다른사람에게 도움이 될 수 있다는 점도 좋았다)

반응형