Programming/Java

Java QR코드 생성 (Image 출력 및 파일저장)

Jan92 2022. 5. 28. 23:19
반응형

QR Code Image 저장 및 출력

해당 포스팅은 Java에서 QR Code를 생성하여 화면으로 출력하는 방법과 이미지 형식으로 저장하는 방법에 대해서 정리한 내용입니다.

 

QR코드는 'Quick Response(빠른 응답)을 뜻하며 흑백의 격자무늬 패턴 방식으로 정보를 나타내는 매트릭스 형식의 2차원 바코드인데요. 기존의 상품 바코드보다 큰 용량으로 많은 양의 정보를 담을 수 있다는 장점이 있습니다.

(QR코드는 숫자 최대 7089자, 문자(ASCll) 최대 4296자를 담을 수 있습니다.)

 

<dependency>
  <groupId>com.google.zxing</groupId>
  <artifactId>javase</artifactId>
  <version>3.4.0</version>
</dependency>

(의존성 추가 / maven)

* 현재 3.4.0 버전에서 심각한 취약점 이슈가 발생되어 다른 버전을 사용하시길 바랍니다.

 

QR Code 생성을 위해서는 'com.google.zxing' 라이브러리를 사용하는데 해당 라이브러리는 구글에서 개발한 오픈소스로 QR Code 스캔 및 바코드 인식 등이 가능합니다.

 

 


 

 

1. QR코드 생성 및 View 형식으로 출력

@GetMapping("/make")
public void makeQr(HttpServletRequest request, HttpServletResponse response) {
    Map<String, Object> model = new HashMap<>();
    model.put("content", "QrCode Information");
    try {
        qrCodeView.renderMergedOutputModel(model, request, response);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

(Controller)

 

@Component
public class QrCodeView extends AbstractView {

    public QrCodeView() {
        setContentType("image/png; charset=UTF-8");
    }

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {
        response.setContentType(getContentType());
        response.setHeader("Content-Transfer-Encoding", "binary");

        OutputStream outputStream = response.getOutputStream();

        QRCodeWriter qrCodeWriter = new QRCodeWriter();

        String content = (String) model.get("content");
        //한글 데이터 처리
        content = new String(content.getBytes(StandardCharsets.UTF_8), "ISO-8859-1");
        //QR 코드 생성 및 출력
        BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 100, 100);
        MatrixToImageWriter.writeToStream(bitMatrix, "png", outputStream);
        outputStream.flush();
    }
}

(AbstractView를 상속받은 QrCodeView class)

 

추상 클래스인 AbstractView를 상속받으면 해당 클래스는 View로 취급되는데요. 여기서 AbstractView를 상속받은 QrCodeView 클래스는 renderMergedOutputModel(...)이라는 추상 메서드를 구현하여 동작하게 됩니다.

 

이때 renderMergedOutputModel() 메서드의 경우 HttpServletRequest, HttpServletResponse를 매개변수로 가지기 때문에 클라이언트에서 요청되는 전달 값들을 받을 수 있으며, 응답하는 데이터의 형식도 설정할 수 있습니다.

 

 

 

2. QR코드 생성 및 이미지 파일로 저장

    @GetMapping("/save")
    public ResponseEntity<?> saveQr(HttpServletRequest request) {
        String savePath = "qrImage";
        File file = new File(savePath);
        //파일 경로가 없으면 파일 생성
        if (!file.exists()) {
            file.mkdirs();
        }

        String content = "https://wildeveloperetrain.tistory.com/";
        String fileName;
        try {
            //QR 생성
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 100, 100);
            BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);

            //yyyyMMddHHmmss 형식의 날짜 및 시간 정보 파일명에 추가
            String datetimeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            fileName = datetimeStr + "qr";
            //파일 생성
            File temp = new File(savePath + "/" + fileName + ".png");

            //ImageIO를 사용하여 파일쓰기
            ImageIO.write(bufferedImage, "png", temp);
        } catch (IOException | WriterException e) {
            e.printStackTrace();
            return response.fail("");
        }
        return response.success(fileName + ".png");
    }

 

(Controller)

 

앞에서 본 뷰 형식으로 출력하는 것과 마찬가지로 핵심은 QRCodeWriter 인스턴스를 통해 QR형식의 BitMatrix 인스턴스를 생성하는 것입니다.

 

차이점이라고 하면 앞에서는 MatrixToImageWriter.writeToStream() 메서드를 사용하여 BitMatrix 객체를 Stream으로 만들었다면,

여기서는 MatrixToImageWriter.toBufferedImage() 메서드를 사용하여 BitMatrix 객체를 BufferedImage 타입으로 만들고 ImageIO의 write() 메서드를 통해 이미지를 저장했다는 것입니다.

(File 생성 부분과 파일명, ImageIO를 사용한 부분은 사용하는 사람에 따라 변할 수 있기 때문에 큰 틀로만 참고 부탁드립니다.)

 

 

 

***

생성된 QR코드를 뷰 형식으로 출력하는 방법과 저장하는 방법, 두 방법을 결합하여 이미지를 저장하면서 출력하는 것도 가능합니다.

반응형