mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
190 lines
7.5 KiB
Java
190 lines
7.5 KiB
Java
/*
|
|
* Copyright 2013 ZXing authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.google.zxing.pdf417;
|
|
|
|
import com.google.zxing.BarcodeFormat;
|
|
import com.google.zxing.BinaryBitmap;
|
|
import com.google.zxing.BufferedImageLuminanceSource;
|
|
import com.google.zxing.DecodeHintType;
|
|
import com.google.zxing.LuminanceSource;
|
|
import com.google.zxing.ReaderException;
|
|
import com.google.zxing.RXingResult;
|
|
import com.google.zxing.RXingResultMetadataType;
|
|
import com.google.zxing.common.AbstractBlackBoxTestCase;
|
|
import com.google.zxing.common.HybridBinarizer;
|
|
import com.google.zxing.common.TestRXingResult;
|
|
|
|
import com.google.zxing.multi.MultipleBarcodeReader;
|
|
import org.junit.Test;
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.IOException;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Comparator;
|
|
import java.util.EnumMap;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.logging.Logger;
|
|
|
|
/**
|
|
* This class tests Macro PDF417 barcode specific functionality. It ensures that information, which is split into
|
|
* several barcodes can be properly combined again to yield the original data content.
|
|
*
|
|
* @author Guenther Grau
|
|
*/
|
|
public final class PDF417BlackBox4TestCase extends AbstractBlackBoxTestCase {
|
|
private static final Logger log = Logger.getLogger(AbstractBlackBoxTestCase.class.getSimpleName());
|
|
|
|
private final MultipleBarcodeReader barcodeReader = new PDF417Reader();
|
|
|
|
private final List<TestRXingResult> testRXingResults = new ArrayList<>();
|
|
|
|
public PDF417BlackBox4TestCase() {
|
|
super("src/test/resources/blackbox/pdf417-4", null, BarcodeFormat.PDF_417);
|
|
testRXingResults.add(new TestRXingResult(3, 3, 0, 0, 0.0f));
|
|
}
|
|
|
|
@Test
|
|
@Override
|
|
public void testBlackBox() throws IOException {
|
|
assertFalse(testRXingResults.isEmpty());
|
|
|
|
Map<String,List<Path>> imageFiles = getImageFileLists();
|
|
int testCount = testRXingResults.size();
|
|
|
|
int[] passedCounts = new int[testCount];
|
|
int[] tryHarderCounts = new int[testCount];
|
|
|
|
Path testBase = getTestBase();
|
|
|
|
for (Entry<String,List<Path>> testImageGroup : imageFiles.entrySet()) {
|
|
log.fine(String.format("Starting Image Group %s", testImageGroup.getKey()));
|
|
|
|
String fileBaseName = testImageGroup.getKey();
|
|
String expectedText;
|
|
Path expectedTextFile = testBase.resolve(fileBaseName + ".txt");
|
|
if (Files.exists(expectedTextFile)) {
|
|
expectedText = readFileAsString(expectedTextFile, StandardCharsets.UTF_8);
|
|
} else {
|
|
expectedTextFile = testBase.resolve(fileBaseName + ".bin");
|
|
assertTrue(Files.exists(expectedTextFile));
|
|
expectedText = readFileAsString(expectedTextFile, StandardCharsets.ISO_8859_1);
|
|
}
|
|
|
|
for (int x = 0; x < testCount; x++) {
|
|
List<RXingResult> results = new ArrayList<>();
|
|
for (Path imageFile : testImageGroup.getValue()) {
|
|
BufferedImage image = ImageIO.read(imageFile.toFile());
|
|
float rotation = testRXingResults.get(x).getRotation();
|
|
BufferedImage rotatedImage = rotateImage(image, rotation);
|
|
LuminanceSource source = new BufferedImageLuminanceSource(rotatedImage);
|
|
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
|
|
|
try {
|
|
results.addAll(Arrays.asList(decode(bitmap, false)));
|
|
} catch (ReaderException ignored) {
|
|
// ignore
|
|
}
|
|
}
|
|
results.sort(Comparator.comparingInt((RXingResult r) -> getMeta(r).getSegmentIndex()));
|
|
StringBuilder resultText = new StringBuilder();
|
|
String fileId = null;
|
|
for (RXingResult result : results) {
|
|
PDF417RXingResultMetadata resultMetadata = getMeta(result);
|
|
assertNotNull("resultMetadata", resultMetadata);
|
|
if (fileId == null) {
|
|
fileId = resultMetadata.getFileId();
|
|
}
|
|
assertEquals("FileId", fileId, resultMetadata.getFileId());
|
|
resultText.append(result.getText());
|
|
}
|
|
assertEquals("ExpectedText", expectedText, resultText.toString());
|
|
passedCounts[x]++;
|
|
tryHarderCounts[x]++;
|
|
}
|
|
}
|
|
|
|
// Print the results of all tests first
|
|
int totalFound = 0;
|
|
int totalMustPass = 0;
|
|
|
|
int numberOfTests = imageFiles.keySet().size();
|
|
for (int x = 0; x < testRXingResults.size(); x++) {
|
|
TestRXingResult testRXingResult = testRXingResults.get(x);
|
|
log.info(String.format("Rotation %d degrees:", (int) testRXingResult.getRotation()));
|
|
log.info(String.format(" %d of %d images passed (%d required)", passedCounts[x], numberOfTests,
|
|
testRXingResult.getMustPassCount()));
|
|
log.info(String.format(" %d of %d images passed with try harder (%d required)", tryHarderCounts[x],
|
|
numberOfTests, testRXingResult.getTryHarderCount()));
|
|
totalFound += passedCounts[x] + tryHarderCounts[x];
|
|
totalMustPass += testRXingResult.getMustPassCount() + testRXingResult.getTryHarderCount();
|
|
}
|
|
|
|
int totalTests = numberOfTests * testCount * 2;
|
|
log.info(String.format("Decoded %d images out of %d (%d%%, %d required)", totalFound, totalTests, totalFound *
|
|
100 /
|
|
totalTests, totalMustPass));
|
|
if (totalFound > totalMustPass) {
|
|
log.warning(String.format("+++ Test too lax by %d images", totalFound - totalMustPass));
|
|
} else if (totalFound < totalMustPass) {
|
|
log.warning(String.format("--- Test failed by %d images", totalMustPass - totalFound));
|
|
}
|
|
|
|
// Then run through again and assert if any failed
|
|
for (int x = 0; x < testCount; x++) {
|
|
TestRXingResult testRXingResult = testRXingResults.get(x);
|
|
String label = "Rotation " + testRXingResult.getRotation() + " degrees: Too many images failed";
|
|
assertTrue(label, passedCounts[x] >= testRXingResult.getMustPassCount());
|
|
assertTrue("Try harder, " + label, tryHarderCounts[x] >= testRXingResult.getTryHarderCount());
|
|
}
|
|
}
|
|
|
|
private static PDF417RXingResultMetadata getMeta(RXingResult result) {
|
|
return result.getRXingResultMetadata() == null ? null : (PDF417RXingResultMetadata) result.getRXingResultMetadata().get(
|
|
RXingResultMetadataType.PDF417_EXTRA_METADATA);
|
|
}
|
|
|
|
private RXingResult[] decode(BinaryBitmap source, boolean tryHarder) throws ReaderException {
|
|
Map<DecodeHintType,Object> hints = new EnumMap<>(DecodeHintType.class);
|
|
if (tryHarder) {
|
|
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
|
|
}
|
|
|
|
return barcodeReader.decodeMultiple(source, hints);
|
|
}
|
|
|
|
private Map<String,List<Path>> getImageFileLists() throws IOException {
|
|
Map<String,List<Path>> result = new HashMap<>();
|
|
for (Path file : getImageFiles()) {
|
|
String testImageFileName = file.getFileName().toString();
|
|
String fileBaseName = testImageFileName.substring(0, testImageFileName.indexOf('-'));
|
|
List<Path> files = result.computeIfAbsent(fileBaseName, k -> new ArrayList<>());
|
|
files.add(file);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|