111 lines
4.4 KiB
Java
111 lines
4.4 KiB
Java
package io.rudefox.cold;
|
|
|
|
import com.google.zxing.BarcodeFormat;
|
|
import com.google.zxing.EncodeHintType;
|
|
import com.google.zxing.WriterException;
|
|
import com.google.zxing.common.BitMatrix;
|
|
import com.google.zxing.qrcode.QRCodeWriter;
|
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
|
|
|
import java.nio.charset.Charset;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
class QRCode {
|
|
|
|
private static final String FALLBACK_SET_STRING = "##";
|
|
|
|
static String toQRCode(String data) {
|
|
|
|
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
|
Map<EncodeHintType, Object> hints = new HashMap<>();
|
|
hints.put(EncodeHintType.MARGIN, 0);
|
|
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
|
|
|
|
BitMatrix bitMatrix = null;
|
|
try {
|
|
bitMatrix = qrCodeWriter.encode(data, BarcodeFormat.QR_CODE, 0, 0, hints);
|
|
} catch (WriterException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
if (bitMatrix == null)
|
|
return "[Error Generating QR Code]";
|
|
|
|
if (charsetDoesNotSupportFullBlockChar())
|
|
return bitMatrix.toString(FALLBACK_SET_STRING, " ");
|
|
|
|
return toUTF8(bitMatrix);
|
|
}
|
|
|
|
private static String toUTF8(BitMatrix bitMatrix) {
|
|
|
|
char SPACE = '\u0020';
|
|
char LOWER_BLOCK = '\u2584';
|
|
char UPPER_BLOCK = '\u2580';
|
|
char FULL_BLOCK = '\u2588';
|
|
|
|
int[] blockCodepoints = new int[] {SPACE, LOWER_BLOCK, UPPER_BLOCK, FULL_BLOCK};
|
|
|
|
StringBuilder qrCode = new StringBuilder();
|
|
|
|
for (int y = 0; y < bitMatrix.getHeight(); y += 2) {
|
|
|
|
for (int x = 0; x < bitMatrix.getWidth(); x++) {
|
|
|
|
int upper_bit = bitMatrix.get(x, y) ? 1 : 0;
|
|
int lower_bit = y+1 < bitMatrix.getHeight() && bitMatrix.get(x, y+1) ? 1 : 0;
|
|
|
|
int index = upper_bit << 1 | lower_bit;
|
|
int blockCodepoint = blockCodepoints[index];
|
|
|
|
qrCode.appendCodePoint(blockCodepoint);
|
|
}
|
|
|
|
if (y < bitMatrix.getHeight() - 1)
|
|
qrCode.append("\n");
|
|
}
|
|
|
|
return qrCode.toString();
|
|
}
|
|
|
|
private static boolean charsetDoesNotSupportFullBlockChar() {
|
|
|
|
Charset charset = ServiceLocator.DEFAULT_CHARSET;
|
|
String charsetString = charset.toString();
|
|
|
|
return charset.equals(StandardCharsets.ISO_8859_1) ||
|
|
charset.equals(StandardCharsets.US_ASCII) ||
|
|
charsetString.equalsIgnoreCase("euc-jp") ||
|
|
charsetString.equalsIgnoreCase("euc-kr") ||
|
|
charsetString.equalsIgnoreCase("iso-2022-jp") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-10") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-13") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-14") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-15") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-16") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-2") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-3") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-4") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-5") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-6") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-7") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-8") ||
|
|
charsetString.equalsIgnoreCase("iso-8859-8-i") ||
|
|
charsetString.equalsIgnoreCase("macintosh") ||
|
|
charsetString.equalsIgnoreCase("shift_jis") ||
|
|
charsetString.equalsIgnoreCase("windows-1250") ||
|
|
charsetString.equalsIgnoreCase("windows-1251") ||
|
|
charsetString.equalsIgnoreCase("windows-1252") ||
|
|
charsetString.equalsIgnoreCase("windows-1253") ||
|
|
charsetString.equalsIgnoreCase("windows-1254") ||
|
|
charsetString.equalsIgnoreCase("windows-1255") ||
|
|
charsetString.equalsIgnoreCase("windows-1256") ||
|
|
charsetString.equalsIgnoreCase("windows-1257") ||
|
|
charsetString.equalsIgnoreCase("windows-1258") ||
|
|
charsetString.equalsIgnoreCase("windows-874") ||
|
|
charsetString.equalsIgnoreCase("x-mac-cyrillic") ||
|
|
charsetString.equalsIgnoreCase("x-user-defined");
|
|
}
|
|
} |