Intro
COVID 19 이후로 정말 많은것이 달라졌습니다. 하나하나 나열하기도 힘든 만큼 일상 생활 속에서 달라진 것 들이 많지만 그 중 하나의 기술을 뽑자면 QR 코드가 아닐까 싶습니다.
아주 오래전부터 있었지만 별다른 주목을 받지 못했고 그렇게 잊혀지는가 했는데 코로나로 인한 방문 기록, 전자문진표 등 조금씩 많이 쓰이는가 싶더니 카카오페이를 비롯한 여러가지 간편결제 서비스가 많아지면서 없어서는 안 될 기술이 되었습니다.
어플리케이션을 만들 때에도 곳곳에 QR코드를 활용 할 일이 많아졌는데요, QR코드 생성 한다면 크게 두가지 방법이 있습니다.
- 구글의 QR Codes API 에 요청
- QR 코드를 작성하는 OpenSource를 활용해 로컬에서 생성
얼핏 보면 외부 API를 활용 하는게 간단해 보이는데 사실 생성해서 내보내는 것도 생각보다 쉽습니다. 아무리 구글이라고는 하지만 API를 유지 해 줄 의무가 있는건 아니기때문에 QR 코드를 직접 생성해서 내보내는 방식으로 진행 해 보도록 하겠습니다.
ZXING
Zxing(Zebra Crossing)는 구글에서 제공하는 오픈 소스인데요, 사실상 QR 코드를 스캔 하는 거의 대부분의 어플리케이션이 해당 프로젝트로 부터 파생되었다고 합니다.
QR Code를 비롯한 다양한 Format을 지원 합니다.
실습
바로 간단한 예제코드를 통해 QR 코드 생성을 해 보도록 하겠습니다. 스프링 부트 프로젝트로 작성 하였습니다.
의존성 추가
pom.xml 파일에 zxing core와 javase 를 추가 해 줍니다.
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.0</version>
</dependency>
요청 페이지
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
QR CODE
<form action="/qr", method="get">
<input type="text" name="url"/><button type="submit">create</button>
</form>
</body>
</html>
QR 코드로 만들 URL 주소를 입력할 페이지를 생성 해 주었습니다. form 태그를 활용했습니다.
위와 같은 간단히 URL을 적을 수 있는 페이지를 만들어 줍니다.
Controller
이번에는 요청을 처리할 컨트롤러를 만들어 줍니다.
QrController.java
@RestController
public class QrController {
@GetMapping("qr")
public Object createQr(@RequestParam String url) throws WriterException, IOException {
int width = 200;
int height = 200;
BitMatrix matrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, width, height);
try (ByteArrayOutputStream out = new ByteArrayOutputStream();) {
MatrixToImageWriter.writeToStream(matrix, "PNG", out);
return ResponseEntity.ok()
.contentType(MediaType.IMAGE_PNG)
.body(out.toByteArray());
}
}
}
url을 특정 높이와 너비의 BitMatrix 로 생성 한 후, MatrixToImageWriter를 활용해서 이미지로 출력 해 주는 코드 입니다.
File로 작성 할 수도 있지만, 보통 일회성 이기 때문에 Stream에 작성 한 뒤에 응답 하도록 했습니다.
이제 프로젝트를 실행 해서 확인해 보겠습니다.
확인
https://shanepark.tistory.com 를 넣고 create 버튼을 클릭 했습니다.
QR 코드가 생성 된 것이 확인 됩니다.
이제 핸드폰 카메라로 확인 해 보면
정상적으로 입력한 페이지로 이동 하는 것이 확인 됩니다.
Documents
마지막으로 QR 코드 이미지 생성에 사용 할 수 있는 필요한 옵션들 몇 가지 알아보겠습니다.
MatrixToImageConfig
https://zxing.github.io/zxing/apidocs/com/google/zxing/client/j2se/MatrixToImageConfig.html
QR코드 이미지 생성 시 색상 옵션을 설정 할 수 있습니다.
MatrixToImageWriter의 writeToStream을 호출 할 때, 마지막 파라미터로 넣어 줄 수 있습니다.
MatrixToImageConfig conf = new MatrixToImageConfig(MatrixToImageConfig.BLACK,-1);
기본적으로는 위에 보이는 기본 세팅으로 되어 있습니다.
public static final int BLACK = -16777216;
public static final int WHITE = -1;
BLACK, WHITE로 되어 있는 기본 값을 원하는 컬러로 설정 할 수 있습니다. 하지만 ARGB 값으로 넣어야 하기 때문에 약간의 변환이 필요합니다. 저는 아래와 같이 코드를 작성해서 입력 받은 HEX값을 변환하도록 했습니다.
int rgb = Color.white.getRGB();
if (offColor != null && offColor.length() == 6) {
try {
int r = Integer.parseInt(offColor.substring(0, 2), 16);
int g = Integer.parseInt(offColor.substring(2, 4), 16);
int b = Integer.parseInt(offColor.substring(4, 6), 16);
rgb = new Color(r, g, b).getRGB();
} catch (NumberFormatException e) {
rgb = Color.white.getRGB();
}
}
QR Code의 배경 색상을 커스터마이징 할 수 있도록 했습니다.
Map<EncodeHintType, Object>
EncodeHintType을 이용해 마진을 설정 하거나 필요한 몇 가지 설정을 할 수 있습니다.
해당 옵션은 MultiFormatWriter의 encode 메서드를 호출 할 때에 hints를 마지막 파라미터로 넣어서 사용 할 수 있습니다.
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.MARGIN, 0);
BitMatrix matrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, width, height, hints);
저는 위의 코드를 작성해 Margin을 0으로 변경했습니다.
위의 작성된 코드와 구조를 활용 한다면 대부분의 경우에서 필요한 결과를 얻을 수 있을 거라고 생각합니다.
이상입니다.
reference
'Programming > Java' 카테고리의 다른 글
[Java] Optional 올바르게 사용하기 (0) | 2022.07.21 |
---|---|
[Java] switch 문이 if-else 보다 효율적인 이유 (0) | 2022.07.09 |
JAVA) 자바에서는 Call By Reference가 불가능 합니다. (0) | 2022.06.06 |
JAVA) Date 를 LocalDateTime 으로, 혹은 그 반대로 변환하기 (0) | 2022.05.23 |
Java) HashMap에서 특정 value를 제거하기 (0) | 2022.05.13 |