mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Add support for encoding GS1 formatted QR (#927)
* Add support for encoding GS1 formatted QR * Place FNC1 mode header after ECI header
This commit is contained in:
parent
561f09b32e
commit
e54e0c781b
|
@ -101,4 +101,10 @@ public enum EncodeHintType {
|
|||
* (Type {@link Integer}, or {@link String} representation of the integer value).
|
||||
*/
|
||||
QR_VERSION,
|
||||
|
||||
/**
|
||||
* Specifies whether the data should be encoded to the GS1 standard (type {@link Boolean}, or "true" or "false"
|
||||
* {@link String } value).
|
||||
*/
|
||||
GS1_FORMAT,
|
||||
}
|
||||
|
|
|
@ -99,6 +99,13 @@ public final class Encoder {
|
|||
}
|
||||
}
|
||||
|
||||
// Append the FNC1 mode header for GS1 formatted data if applicable
|
||||
boolean hasGS1FormatHint = hints != null && hints.containsKey(EncodeHintType.GS1_FORMAT);
|
||||
if (hasGS1FormatHint && Boolean.valueOf(hints.get(EncodeHintType.GS1_FORMAT).toString())) {
|
||||
// GS1 formatted codes are prefixed with a FNC1 in first position mode header
|
||||
appendModeInfo(Mode.FNC1_FIRST_POSITION, headerBits);
|
||||
}
|
||||
|
||||
// (With ECI in place,) Write the mode marker
|
||||
appendModeInfo(mode, headerBits);
|
||||
|
||||
|
|
|
@ -255,6 +255,76 @@ public final class EncoderTestCase extends Assert {
|
|||
assertEquals(expected, qrCode.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeGS1WithStringTypeHint() throws WriterException {
|
||||
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
|
||||
hints.put(EncodeHintType.GS1_FORMAT, "true");
|
||||
QRCode qrCode = Encoder.encode("100001%11171218", ErrorCorrectionLevel.H, hints);
|
||||
verifyGS1EncodedData(qrCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeGS1WithBooleanTypeHint() throws WriterException {
|
||||
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
|
||||
hints.put(EncodeHintType.GS1_FORMAT, true);
|
||||
QRCode qrCode = Encoder.encode("100001%11171218", ErrorCorrectionLevel.H, hints);
|
||||
verifyGS1EncodedData(qrCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotEncodeGS1WhenBooleanTypeHintExplicitlyFalse() throws WriterException {
|
||||
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
|
||||
hints.put(EncodeHintType.GS1_FORMAT, false);
|
||||
QRCode qrCode = Encoder.encode("ABCDEF", ErrorCorrectionLevel.H, hints);
|
||||
verifyNotGS1EncodedData(qrCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotEncodeGS1WhenStringTypeHintExplicitlyFalse() throws WriterException {
|
||||
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
|
||||
hints.put(EncodeHintType.GS1_FORMAT, "false");
|
||||
QRCode qrCode = Encoder.encode("ABCDEF", ErrorCorrectionLevel.H, hints);
|
||||
verifyNotGS1EncodedData(qrCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGS1ModeHeaderWithECI() throws WriterException {
|
||||
Map<EncodeHintType,Object> hints = new EnumMap<>(EncodeHintType.class);
|
||||
hints.put(EncodeHintType.CHARACTER_SET, "UTF8");
|
||||
hints.put(EncodeHintType.GS1_FORMAT, true);
|
||||
QRCode qrCode = Encoder.encode("hello", ErrorCorrectionLevel.H, hints);
|
||||
String expected =
|
||||
"<<\n" +
|
||||
" mode: BYTE\n" +
|
||||
" ecLevel: H\n" +
|
||||
" version: 1\n" +
|
||||
" maskPattern: 5\n" +
|
||||
" matrix:\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 1 1 1 1 1 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 0 1 0 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 1 1 1 1 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0\n" +
|
||||
" 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0 1 0 1 0 1\n" +
|
||||
" 0 1 0 1 1 0 0 1 0 1 1 1 1 1 1 0 1 1 1 0 1\n" +
|
||||
" 0 1 0 1 1 1 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0\n" +
|
||||
" 1 1 1 1 0 1 0 1 0 0 1 0 1 0 0 1 1 1 1 0 0\n" +
|
||||
" 1 0 0 1 0 0 1 1 0 1 1 0 1 0 1 0 0 1 0 0 1\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 0 1 0 0 1 0\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 0 1 1 0 0 1 0 0 0 1 1 0\n" +
|
||||
" 1 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 1 1 0 0\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 0 1 0 1 0 1 0 0 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 0 1 1 1 1 0\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 0 1 0 1 1 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 0 1 1 1 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 1 0 0 1 0\n" +
|
||||
">>\n";
|
||||
assertEquals(expected, qrCode.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppendModeInfo() {
|
||||
BitArray bits = new BitArray();
|
||||
|
@ -594,6 +664,76 @@ public final class EncoderTestCase extends Assert {
|
|||
Encoder.encode(builder.toString(), ErrorCorrectionLevel.L);
|
||||
}
|
||||
|
||||
private void verifyGS1EncodedData(QRCode qrCode) {
|
||||
String expected =
|
||||
"<<\n" +
|
||||
" mode: ALPHANUMERIC\n" +
|
||||
" ecLevel: H\n" +
|
||||
" version: 2\n" +
|
||||
" maskPattern: 4\n" +
|
||||
" matrix:\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 1 1 0 1 1 0 1 1 0 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0\n" +
|
||||
" 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 0\n" +
|
||||
" 0 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1\n" +
|
||||
" 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0\n" +
|
||||
" 1 0 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 0 0\n" +
|
||||
" 0 1 0 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1 0 0 0 0 0 1 0\n" +
|
||||
" 1 0 0 1 1 1 0 0 1 1 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0\n" +
|
||||
" 0 0 1 0 0 1 1 1 0 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 0\n" +
|
||||
" 0 0 0 1 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 1 0\n" +
|
||||
" 1 1 0 1 0 1 1 0 1 0 1 0 0 0 1 1 1 1 1 1 1 0 0 0 0\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 1 0 0 0 1 1 0 1 0\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0\n" +
|
||||
" 1 0 0 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 0 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 0 0 0\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 1 1 1 0 1 1 0 0 1 0\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 1 1 0 1 1 1 1 1 0 1 0 1 1 0 0 0\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 1 1 0 0 1 1 0 0 1 1\n" +
|
||||
">>\n";
|
||||
assertEquals(expected, qrCode.toString());
|
||||
}
|
||||
|
||||
private void verifyNotGS1EncodedData(QRCode qrCode) {
|
||||
String expected =
|
||||
"<<\n" +
|
||||
" mode: ALPHANUMERIC\n" +
|
||||
" ecLevel: H\n" +
|
||||
" version: 1\n" +
|
||||
" maskPattern: 4\n" +
|
||||
" matrix:\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 1 0 1 0 0 1 1 1 1 1 1 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 0 1 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0\n" +
|
||||
" 0 0 0 0 1 1 1 1 0 1 1 0 1 0 1 1 0 0 0 1 0\n" +
|
||||
" 0 0 0 0 1 1 0 1 1 1 0 0 1 1 1 1 0 1 1 0 1\n" +
|
||||
" 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 1 1 0 1 1\n" +
|
||||
" 1 0 0 1 1 1 0 0 1 1 1 1 0 0 0 0 1 0 0 0 0\n" +
|
||||
" 0 1 1 1 1 1 1 0 1 0 1 0 1 1 1 0 0 1 1 0 0\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 0 0\n" +
|
||||
" 1 0 0 0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 1 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 0 0 0 1 1 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 1 0 0 0 1 1 0 0 0 0\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0 1 1 1\n" +
|
||||
">>\n";
|
||||
assertEquals(expected, qrCode.toString());
|
||||
}
|
||||
|
||||
private static String shiftJISString(byte[] bytes) throws WriterException {
|
||||
try {
|
||||
return new String(bytes, "Shift_JIS");
|
||||
|
|
Loading…
Reference in a new issue