From bc07a778ba66375b95751ab7e77b82395d65a3b5 Mon Sep 17 00:00:00 2001 From: dswitkin Date: Tue, 26 May 2009 16:39:00 +0000 Subject: [PATCH] Extended the command line tool to dump the results of black point calculation. You can now use the flag --dump_black_point to generate a PNG which contains the original image, the row scanning monochrome version, and the 2D scanning monochrome version side by side. It will be saved as originalfilename.mono.png. git-svn-id: http://zxing.googlecode.com/svn/trunk@953 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../zxing/client/j2se/CommandLineRunner.java | 111 +++++++++++++++++- 1 file changed, 105 insertions(+), 6 deletions(-) diff --git a/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java b/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java index 235950ed..48913cf9 100644 --- a/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java +++ b/javase/src/com/google/zxing/client/j2se/CommandLineRunner.java @@ -16,6 +16,7 @@ package com.google.zxing.client.j2se; +import com.google.zxing.BlackPointEstimationMethod; import com.google.zxing.DecodeHintType; import com.google.zxing.MonochromeBitmapSource; import com.google.zxing.MultiFormatReader; @@ -23,6 +24,7 @@ import com.google.zxing.ReaderException; import com.google.zxing.Result; import com.google.zxing.client.result.ParsedResult; import com.google.zxing.client.result.ResultParser; +import com.google.zxing.common.BitArray; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; @@ -30,6 +32,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.URI; @@ -54,12 +57,15 @@ public final class CommandLineRunner { public static void main(String[] args) throws Exception { Hashtable hints = null; boolean dumpResults = false; + boolean dumpBlackPoint = false; for (String arg : args) { if ("--try_harder".equals(arg)) { hints = new Hashtable(3); hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); } else if ("--dump_results".equals(arg)) { dumpResults = true; + } else if ("--dump_black_point".equals(arg)) { + dumpBlackPoint = true; } else if (arg.startsWith("--")) { System.out.println("Unknown command line option " + arg); return; @@ -67,13 +73,14 @@ public final class CommandLineRunner { } for (String arg : args) { if (!arg.startsWith("--")) { - decodeOneArgument(arg, hints, dumpResults); + decodeOneArgument(arg, hints, dumpResults, dumpBlackPoint); } } } private static void decodeOneArgument(String argument, Hashtable hints, - boolean dumpResults) throws IOException, URISyntaxException { + boolean dumpResults, boolean dumpBlackPoint) throws IOException, + URISyntaxException { File inputFile = new File(argument); if (inputFile.exists()) { @@ -86,7 +93,11 @@ public final class CommandLineRunner { if (filename.startsWith(".") || filename.endsWith(".txt")) { continue; } - Result result = decode(input.toURI(), hints); + // Skip the results of dumping the black point. + if (filename.contains(".mono.png")) { + continue; + } + Result result = decode(input.toURI(), hints, dumpBlackPoint); if (result != null) { successful++; if (dumpResults) { @@ -98,13 +109,13 @@ public final class CommandLineRunner { System.out.println("\nDecoded " + successful + " files out of " + total + " successfully (" + (successful * 100 / total) + "%)\n"); } else { - Result result = decode(inputFile.toURI(), hints); + Result result = decode(inputFile.toURI(), hints, dumpBlackPoint); if (dumpResults) { dumpResult(inputFile, result); } } } else { - decode(new URI(argument), hints); + decode(new URI(argument), hints, dumpBlackPoint); } } @@ -127,7 +138,8 @@ public final class CommandLineRunner { } } - private static Result decode(URI uri, Hashtable hints) throws IOException { + private static Result decode(URI uri, Hashtable hints, + boolean dumpBlackPoint) throws IOException { BufferedImage image; try { image = ImageIO.read(uri.toURL()); @@ -140,6 +152,9 @@ public final class CommandLineRunner { } try { MonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image); + if (dumpBlackPoint) { + dumpBlackPoint(uri, image, source); + } Result result = new MultiFormatReader().decode(source, hints); ParsedResult parsedResult = ResultParser.parseResult(result); System.out.println(uri.toString() + " (format: " + result.getBarcodeFormat() + @@ -152,4 +167,88 @@ public final class CommandLineRunner { } } + // Writes out a single PNG which is three times the width of the input image, containing from left + // to right: the original image, the row sampling monochrome version, and the 2D sampling + // monochrome version. + // TODO: Currently fails on URLs. Would be nice to handle gracefully and write the output to pwd. + private static void dumpBlackPoint(URI uri, BufferedImage image, MonochromeBitmapSource source) { + String inputName = uri.getPath(); + if (inputName.contains(".mono.png")) { + return; + } + + int width = source.getWidth(); + int height = source.getHeight(); + int stride = width * 3; + int[] pixels = new int[stride * height]; + + // The original image + int[] argb = new int[width]; + for (int y = 0; y < height; y++) { + image.getRGB(0, y, width, 1, argb, 0, width); + System.arraycopy(argb, 0, pixels, y * stride, width); + } + argb = null; + + // Row sampling + BitArray row = new BitArray(width); + for (int y = 0; y < height; y++) { + try { + source.estimateBlackPoint(BlackPointEstimationMethod.ROW_SAMPLING, y); + } catch (ReaderException e) { + // If the row histogram failed, draw a red line and keep going + int offset = y * stride + width; + for (int x = 0; x < width; x++) { + pixels[offset + x] = 0xffff0000; + } + continue; + } + source.getBlackRow(y, row, 0, width); + int offset = y * stride + width; + for (int x = 0; x < width; x++) { + if (row.get(x)) { + pixels[offset + x] = 0xff000000; + } else { + pixels[offset + x] = 0xffffffff; + } + } + } + + // 2D sampling + try { + source.estimateBlackPoint(BlackPointEstimationMethod.TWO_D_SAMPLING, 0); + for (int y = 0; y < height; y++) { + source.getBlackRow(y, row, 0, width); + int offset = y * stride + width * 2; + for (int x = 0; x < width; x++) { + if (row.get(x)) { + pixels[offset + x] = 0xff000000; + } else { + pixels[offset + x] = 0xffffffff; + } + } + } + } catch (ReaderException e) { + } + + // Write the result + BufferedImage result = new BufferedImage(stride, height, BufferedImage.TYPE_INT_ARGB); + result.setRGB(0, 0, stride, height, pixels, 0, stride); + + String resultName = inputName; + int pos = resultName.lastIndexOf('.'); + if (pos > 0) { + resultName = resultName.substring(0, pos); + } + resultName += ".mono.png"; + try { + OutputStream outStream = new FileOutputStream(resultName); + ImageIO.write(result, "png", outStream); + } catch (FileNotFoundException e) { + System.out.println("Could not create " + resultName); + } catch (IOException e) { + System.out.println("Could not write to " + resultName); + } + } + } -- 2.20.1