삶 가운데 남긴 기록 AACII.TISTORY.COM
String을 QR코드로 변환 com.google.zxing 라이브러리 본문
com.google.zxing 라이브러리
아래는 Zxing Core 3.5.x 버전을 기반으로 한 예제입니다.
maven이나 gradle 등을 통해 라이브러리를 프로젝트에 추가할 수 있습니다.
다만 너무 최근 버전보다 안정화된 버전을 사용하는 것을 권장드립니다.
이 zxing 라이브러리는 String을 QR 코드로, 다시 QR코드를 String으로 복원할 수 있습니다.
QR 코드 스펙상 문자열의 길이의 제한이 있을 수 있습니다.
인코딩 방식이나 오류 레벨 설정 라이브러리 종류나 버전 등에 따라 차이가 있을 수 있지만 수백 글자에서 수천 자까지만 가능합니다.
따라서 긴 문자열은 QR코드를 여러개로 분할하여 변환해야 합니다.
아래 예제는 긴 문자열을 1000 글자로 나누어서 QR 코드로 변환 후 다시 String으로 복원하는 예제입니다.
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class QRCodeExample {
public static void main(String[] args) {
String longString = "긴 문자열 내용..."; // 여기에 실제 긴 문자열을 넣으세요.
// 문자열을 1000글자씩 나누어 QR 코드 이미지로 변환
String[] dividedStrings = divideString(longString, 1000);
for (int i = 0; i < dividedStrings.length; i++) {
String text = dividedStrings[i];
generateQRCode(text, "QRCodePart" + (i + 1) + ".png");
}
// QR 코드 이미지를 읽어서 문자열로 복원
StringBuilder reconstructedString = new StringBuilder();
for (int i = 0; i < dividedStrings.length; i++) {
String decodedText = decodeQRCode("QRCodePart" + (i + 1) + ".png");
reconstructedString.append(decodedText);
}
System.out.println("Reconstructed String: " + reconstructedString.toString());
}
private static String[] divideString(String input, int chunkSize) {
int length = input.length();
int numOfChunks = (int) Math.ceil((double) length / chunkSize);
String[] result = new String[numOfChunks];
for (int i = 0; i < numOfChunks; i++) {
int start = i * chunkSize;
int end = Math.min((i + 1) * chunkSize, length);
result[i] = input.substring(start, end);
}
return result;
}
private static void generateQRCode(String text, String filePath) {
String format = "png";
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
try {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, 0, 0, hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
File qrCodeFile = new File(filePath);
ImageIO.write(image, format, qrCodeFile);
System.out.println("QR Code generated successfully: " + filePath);
} catch (WriterException | IOException e) {
e.printStackTrace();
}
}
private static String decodeQRCode(String filePath) {
BufferedImage bufferedImage;
Result result = null;
try {
bufferedImage = ImageIO.read(new File(filePath));
BinaryBitmap binaryBitmap = new BinaryBitmap(
new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
result = new MultiFormatReader().decode(binaryBitmap);
} catch (IOException | NotFoundException e) {
e.printStackTrace();
}
if (result != null) {
return result.getText();
} else {
return "";
}
}
}
ErrorCorrectionLevel
generateQRCode() 메서드에서 QR코드로 변환할 때의 ErrorCorrectionLevel은 QR 코드의 오류 정정 레벨을 나타냅니다.
오류 정정 레벨은 QR 코드가 불완전하거나 손상된 상태에서도 정확하게 읽을 수 있도록 하는 기술입니다.
이 ErrorCorrectionLevel에 따라서 변환할 수 있는 String의 길이가 달라질 수 있으므로 검토 후 결정해야 합니다.
- H (High): 가장 높은 오류 정정 레벨입니다. 높은 오류 정정 레벨은 데이터에 대한 추가적인 비트를 사용하여 더 많은 오류를 감지하고 수정할 수 있습니다. 하지만, QR 코드로 변환할 수 있는 데이터 용량이 감소할 수 있습니다.
- L (Low): 가장 낮은 오류 정정 레벨입니다. 낮은 오류 정정 레벨은 추가 오류 정정을 최소화하고 QR 코드로 변환할 수 있는 데이터 용량을 최대화합니다. 그러나 손상된 상태에서 읽기가 어려울 수 있습니다.
- M (Medium): 중간 수준의 오류 정정 레벨입니다. M은 오류 정정과 데이터 용량 사이의 균형을 제공합니다. 일반적으로 대부분의 상황에서 적절한 선택입니다.
- Q (Quartile): 중간에서 높은 수준의 오류 정정 레벨입니다. Q는 높은 정정 능력을 가지면서도 H보다는 데이터 용량을 보다 효율적으로 사용합니다.
UTF-8의 경우 변환 상 주의 할 점
UTF-8에서 각 문자는 1바이트에서 4바이트까지의 길이가 달라질 수 있는 특성이 있습니다.
- 숫자: 1자리당 1바이트
- 알파벳 및 특수 문자: 1자리당 1바이트
- 한글 등 다국어 문자: 1자리당 3바이트
그래서 UTF-8로 인코딩 된 문자열의 경우, QR 코드의 데이터 용량은 한글이 많은 경우와 그렇지 않은 경우에 따라서 변환할 수 있는 문자열의 길이가 변할 수 있는 것입니다.
일반적으로 3,000 ~ 4,000바이트 정도의 데이터를 담을 수 있는 QR 코드를 생성하는 것이 가능합니다.
그러나 한글이 들어가있는 경우인가 아닌가에 따라서 글자수 길이를 적절히 제한해야 합니다.
QR 코드의 레벨 및 버전 등을 고려하여 테스트해 보는 것이 가장 확실한 방법입니다.
아래는 테스트로 생성한 QR코드입니다. 위 내용으로 되어있습니다.
'DEV&OPS > Java' 카테고리의 다른 글
자바 Thread dump (0) | 2024.01.20 |
---|---|
[SWT/JFace] Widget, Control, Label, Button (1) | 2024.01.20 |
[SWT/JFace] 모델 기반 어댑터 (76) | 2024.01.18 |
[SWT/JFace] Display 클래스, Shell 클래스, 메시지 박스 예제 (81) | 2024.01.16 |
[SWT/JFace] 이클립스 플러그인 개발 환경 설정 (3) | 2024.01.16 |