본문 바로가기
dev/spring

Spring AI 영수증 이미지 처리하기

by igooo 2025. 1. 21.
728x90

개요

Spring AI를 사용하여 영수증 이미지 파일에 총액과 상품 정보를 조회하여 화면에 출력하는 기능을 개발한다.

Spring AI와 OpenAI를 사용하면 매우 적은 코드로 간단하게 AI기능을 구현할 수 있다.

 

Getting started

Spring Initializr

AI 연동을 위해서 OpenAI를 추가하고, Frontend를 위해서 간단한 Vaandi 의존성을 추가하여 프로젝트를 생성한다.

 

Config application.properties

  • 이미지 파일 업로드를 위해서 multipart 업로드 사이즈를 설정한다.
  • OpenAI와 연동을 위해서 사용하는 모델과 API Key를 입력한다.

(참고 https://blog.igooo.org/150)

spring.application.name=ai-receipt
vaadin.launch-browser=true
spring.servlet.multipart.max-file-size=10MB

spring.ai.openai.api-key= << API_KEY >>
spring.ai.openai.chat.options.model=gpt-4o

 

Frontend 개발

화면은 이미지를 업로드할 수 있는 버튼 하나를 추가하고, 영수증 이미지가 정상적으로 업로드되면 Spring AI의 ChatClient를 통해 영수증의 상세 정보를 조회해서 Receipt 객체로(JSON) 응답을 받는다.

@Route
class MainView extends VerticalLayout {
	private final ChatService chatService;

	MainView(ChatService chatService) {
		this.chatService = chatService;

		initFrontend();
	}

	private void initFrontend() {
		var text = new Text("영수증 업로드");
		var buffer = new MemoryBuffer();
		var uploadBtn = new Upload(buffer);
		uploadBtn.setAcceptedFileTypes("image/*");
		uploadBtn.addSucceededListener((event) -> {
			var receipt = this.chatService.prompt("첨부된 영수증을 읽고 제공한 포멧으로 응답해주세요.", event.getMIMEType(), buffer.getInputStream(), Receipt.class);
			showReceipt(receipt);
		});
		add(text, uploadBtn);
	}

	private void showReceipt(Receipt receipt) {
		var items = new Grid<>(Receipt.Item.class);
		items.setItems(receipt.items());

		add(
				new H3("영수증 상세"),
				new Paragraph("상품: " + receipt.merchant()),
				new Paragraph("전체: " + receipt.total()),
				items
		);
	}
}

public record Receipt(String merchant, double total, List<Item> items) {

	public record Item(String name, int quantity, double price) {
	}
}

 

 

Demo

추가적인 코드는 있지만 중요한 코드는 개발이 완료되었다.

서버를 실행해 보면 아래와 같은 화면을 볼 수 있다.

 

영수증 이미지 파일을 등록한다.

 

 

요약

Spring AI를 사용하여 영수증 이미지를 처리하는 방법을 알아보았다. 짧은 코드로 AI를 연동하고 잘 동작하는 서비스를 개발할 수 있다.

 

전체 소스코드는 GitHub에서 확인할 수 있습니다.

 

 

 

 

 

728x90