mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Add more hints for Aztec encoding
git-svn-id: https://zxing.googlecode.com/svn/trunk@2587 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
cd8985336d
commit
883751b8ba
|
@ -27,6 +27,8 @@ public enum EncodeHintType {
|
|||
* Specifies what degree of error correction to use, for example in QR Codes.
|
||||
* Type depends on the encoder. For example for QR codes it's type
|
||||
* {@link com.google.zxing.qrcode.decoder.ErrorCorrectionLevel ErrorCorrectionLevel}.
|
||||
* For Aztec it is of type {@link Integer}, representing the minimal percentage of error correction words.
|
||||
* Note: an Aztec symbol should have a minimum of 25% EC words.
|
||||
*/
|
||||
ERROR_CORRECTION,
|
||||
|
||||
|
|
|
@ -26,17 +26,29 @@ import com.google.zxing.common.BitMatrix;
|
|||
|
||||
public final class AztecWriter implements Writer {
|
||||
|
||||
private static final Charset LATIN_1 = Charset.forName("ISO-8859-1");
|
||||
private static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
|
||||
|
||||
@Override
|
||||
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height) {
|
||||
AztecCode aztec = Encoder.encode(contents.getBytes(LATIN_1), 30);
|
||||
return aztec.getMatrix();
|
||||
return encode(contents, format, DEFAULT_CHARSET, Encoder.DEFAULT_EC_PERCENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType,?> hints) {
|
||||
return encode(contents, format, width, height);
|
||||
String charset = (String) hints.get(EncodeHintType.CHARACTER_SET);
|
||||
Number eccPercent = (Number) hints.get(EncodeHintType.ERROR_CORRECTION);
|
||||
return encode(contents,
|
||||
format,
|
||||
charset == null ? DEFAULT_CHARSET : Charset.forName(charset),
|
||||
eccPercent == null ? Encoder.DEFAULT_EC_PERCENT : eccPercent.intValue());
|
||||
}
|
||||
|
||||
private static BitMatrix encode(String contents, BarcodeFormat format, Charset charset, int eccPercent) {
|
||||
if (format != BarcodeFormat.AZTEC) {
|
||||
throw new IllegalArgumentException("Can only encode QR_AZTECCODE, but got " + format);
|
||||
}
|
||||
AztecCode aztec = Encoder.encode(contents.getBytes(charset), eccPercent);
|
||||
return aztec.getMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,12 +18,17 @@ package com.google.zxing.aztec.encoder;
|
|||
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.zxing.FormatException;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.EncodeHintType;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.aztec.AztecDetectorResult;
|
||||
import com.google.zxing.aztec.decoder.Decoder;
|
||||
|
@ -120,6 +125,23 @@ public final class EncoderTest extends Assert {
|
|||
"X X X X X X X X X X X X X \n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAztecWriter() throws Exception {
|
||||
testWriter("\u20AC 1 sample data.", "ISO-8859-1", 25, true, 2);
|
||||
testWriter("\u20AC 1 sample data.", "ISO-8859-15", 25, true, 2);
|
||||
testWriter("\u20AC 1 sample data.", "UTF-8", 25, true, 2);
|
||||
testWriter("\u20AC 1 sample data.", "UTF-8", 100, true, 3);
|
||||
testWriter("\u20AC 1 sample data.", "UTF-8", 300, true, 4);
|
||||
testWriter("\u20AC 1 sample data.", "UTF-8", 500, false, 5);
|
||||
// Test AztecWriter defaults
|
||||
String data = "In ut magna vel mauris malesuada";
|
||||
AztecWriter writer = new AztecWriter();
|
||||
BitMatrix matrix = writer.encode(data, BarcodeFormat.AZTEC, 0, 0);
|
||||
AztecCode aztec = Encoder.encode(data.getBytes(LATIN_1), Encoder.DEFAULT_EC_PERCENT);
|
||||
BitMatrix expectedMatrix = aztec.getMatrix();
|
||||
assertEquals(matrix, expectedMatrix);
|
||||
}
|
||||
|
||||
// synthetic tests (encode-decode round-trip)
|
||||
|
||||
@Test
|
||||
|
@ -277,7 +299,8 @@ public final class EncoderTest extends Assert {
|
|||
testHighLevelEncodeString("\0a\u00FF\u0080 A",
|
||||
"XXXXX ..X.. ........ .XX....X XXXXXXXX X....... ....X ...X.");
|
||||
// binary long form optimization into 2 short forms (saves 1 bit)
|
||||
testHighLevelEncodeString("\0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 \u0082\u0084\u0088\0 \0\0\0\0 \0\0\0\0 ",
|
||||
testHighLevelEncodeString(
|
||||
"\0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 \u0082\u0084\u0088\0 \0\0\0\0 \0\0\0\0 ",
|
||||
"XXXXX XXXXX ........ ........ ........ ........ ..X....." +
|
||||
" ........ ........ ........ ........ ..X....." +
|
||||
" ........ ........ ........ ........ ..X....." +
|
||||
|
@ -288,7 +311,9 @@ public final class EncoderTest extends Assert {
|
|||
" ........ ........ ........ ........ ..X....." +
|
||||
" ........ ........ ........ ........ ..X.....");
|
||||
// binary long form
|
||||
testHighLevelEncodeString("\0\0\0\0 \0\0\1\0 \0\0\2\0 \0\0\3\0 \0\0\4\0 \0\0\5\0 \0\0\6\0 \0\0\7\0 \0\0\u0008\0 \0\0\u0009\0 \0\0\u00F0\0 \0\0\u00F1\0 \0\0\u00F2\0A",
|
||||
testHighLevelEncodeString(
|
||||
"\0\0\0\0 \0\0\1\0 \0\0\2\0 \0\0\3\0 \0\0\4\0 \0\0\5\0 \0\0\6\0 \0\0\7\0 \0\0\u0008" +
|
||||
"\0 \0\0\u0009\0 \0\0\u00F0\0 \0\0\u00F1\0 \0\0\u00F2\0A",
|
||||
"XXXXX ..... .....X...X. ........ ........ ........ ........ ..X....." +
|
||||
" ........ ........ .......X ........ ..X....." +
|
||||
" ........ ........ ......X. ........ ..X....." +
|
||||
|
@ -334,6 +359,46 @@ public final class EncoderTest extends Assert {
|
|||
assertEquals(data, res.getText());
|
||||
}
|
||||
|
||||
private static void testWriter(String data,
|
||||
String charset,
|
||||
int eccPercent,
|
||||
boolean compact,
|
||||
int layers) throws FormatException {
|
||||
// 1. Perform an encode-decode round-trip because it can be lossy.
|
||||
// 2. Aztec Decoder currently always decodes the data with a LATIN-1 charset:
|
||||
String expectedData = new String(data.getBytes(Charset.forName(charset)), LATIN_1);
|
||||
Map<EncodeHintType,Object> hints = new EnumMap<EncodeHintType,Object>(EncodeHintType.class);
|
||||
hints.put(EncodeHintType.CHARACTER_SET, charset);
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, eccPercent);
|
||||
AztecWriter writer = new AztecWriter();
|
||||
BitMatrix matrix = writer.encode(data, BarcodeFormat.AZTEC, 0, 0, hints);
|
||||
AztecCode aztec = Encoder.encode(data.getBytes(Charset.forName(charset)), eccPercent);
|
||||
assertEquals("Unexpected symbol format (compact)", compact, aztec.isCompact());
|
||||
assertEquals("Unexpected nr. of layers", layers, aztec.getLayers());
|
||||
BitMatrix matrix2 = aztec.getMatrix();
|
||||
assertEquals(matrix, matrix2);
|
||||
AztecDetectorResult r =
|
||||
new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers());
|
||||
DecoderResult res = new Decoder().decode(r);
|
||||
assertEquals(expectedData, res.getText());
|
||||
// Check error correction by introducing up to eccPercent errors
|
||||
int ecWords = aztec.getCodeWords() * eccPercent / 100;
|
||||
Random random = getPseudoRandom();
|
||||
for (int i = 0; i < ecWords; i++) {
|
||||
// don't touch the core
|
||||
int x = random.nextBoolean() ?
|
||||
random.nextInt(aztec.getLayers() * 2)
|
||||
: matrix.getWidth() - 1 - random.nextInt(aztec.getLayers() * 2);
|
||||
int y = random.nextBoolean() ?
|
||||
random.nextInt(aztec.getLayers() * 2)
|
||||
: matrix.getHeight() - 1 - random.nextInt(aztec.getLayers() * 2);
|
||||
matrix.flip(x, y);
|
||||
}
|
||||
r = new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers());
|
||||
res = new Decoder().decode(r);
|
||||
assertEquals(expectedData, res.getText());
|
||||
}
|
||||
|
||||
static Random getPseudoRandom() {
|
||||
return new SecureRandom(new byte[] {(byte) 0xDE, (byte) 0xAD, (byte) 0xBE, (byte) 0xEF});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue