Re: Announcing QR Decoder for ImageJ

Posted by dscho on
URL: http://imagej.273.s1.nabble.com/Announcing-QR-Decoder-for-ImageJ-tp3683501p3683504.html

Hi Elliot,

On Fri, 12 Aug 2011, Elliott Slaughter wrote:

> On Fri, Aug 12, 2011 at 3:34 AM, Johannes Schindelin <
> [hidden email]> wrote:
>
> > On Sun, 31 Jul 2011, Elliott Slaughter wrote:
> >
> > > As a weekend project I built a QR decoder plugin for ImageJ. With
> > > the help of the ZXing project <http://code.google.com/p/zxing/>,
> > > this turned out to be easier than I expected.
> > >
> > > I built the plugin with just QR barcodes in mind, but it would be
> > > easy enough to support other formats as well, if there is demand for
> > > it.
> > >
> > > You can download the plugin here:
> > >
> > https://bitbucket.org/elliottslaughter/qr_decoder/downloads/qr_decoder_1.0.jar
> > >
> > > You can obtain the source code for the plugin here:
> > >
> > > https://bitbucket.org/elliottslaughter/qr_decoder
> >
> > Nice. I made the following change so that the attached image can be
> > decoded. In total, I made these changes:
> >
> > - support all image input types
> > - abort in case of failure, rather than showing a failed result
> > - as a consequence, I do not need the GenericDialog anymore.
> >
>
> Cool.
>
> Would you mind explaining to me (as a relative macro noob) how to catch
> these aborts in a macro such that I can use your version of the plugin
> on a batch of images without stopping in the middle of the set of images
> because one of them couldn't be read?

My version of the plugin would simply abort. This is what I'd expect of a
plugin that can be recorded into a macro with no other error handling than
aborting.

For the macro you have in mind, I'd rather have something like this:

-- snipsnap --
From 8549a75e950db8d159bb593fe7831606b1f0abb8 Mon Sep 17 00:00:00 2001
From: Johannes Schindelin <[hidden email]>
Date: Mon, 15 Aug 2011 01:31:53 -0700
Subject: [PATCH] Refactor to provide a macro-call()able function

Now you can write a macro like this:

        result = call("QR_Decoder.decode");
        if (result == "")
                showMessage("Failure!");
        else
                ...

Signed-off-by: Johannes Schindelin <[hidden email]>
---
 src/QR_Decoder.java |   35 +++++++++++++++++++++++++----------
 1 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/src/QR_Decoder.java b/src/QR_Decoder.java
index 8077f0e..6deed3d 100644
--- a/src/QR_Decoder.java
+++ b/src/QR_Decoder.java
@@ -1,5 +1,6 @@
 import ij.ImagePlus;
 import ij.Macro;
+import ij.WindowManager;
 import ij.gui.GenericDialog;
 import ij.plugin.filter.PlugInFilter;
 import ij.process.ByteProcessor;
@@ -49,6 +50,16 @@ public class QR_Decoder implements PlugInFilter {
  }
 
  public void run(ImageProcessor ip) {
+ try {
+ String resultText = decode(ip);
+ new TextWindow("QR Code", resultText, 12 * resultText.length(), 150);
+ } catch (Exception e) {
+ // Abort on error
+ Macro.abort();
+ }
+ }
+
+ public static String decode(ImageProcessor ip) throws Exception {
  if (!(ip instanceof ByteProcessor))
  ip = ip.convertToByte(true);
  else if (!ip.isDefaultLut())
@@ -57,18 +68,22 @@ public class QR_Decoder implements PlugInFilter {
  BufferedImage myimg = ip.getBufferedImage();
  LuminanceSource source = new BufferedImageLuminanceSource(myimg);
  BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
- String resultText = "FAILED";
+ Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
+ hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
+ Result result = reader.decode(bitmap, hints);
+ return result.getText();
+ }
+
+ /**
+ * Call this function from a macro with
+ *
+ * <pre>result = call("QR_Decoder.decode");
+ */
+ public static String decode() {
  try {
- Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
- hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
- Result result = reader.decode(bitmap, hints);
- resultText = result.getText();
- // On errors just return the default result.
+ return decode(WindowManager.getCurrentImage().getProcessor());
  } catch (Exception e) {
- Macro.abort();
+ return "";
  }
-
- new TextWindow("QR Code", resultText, 12 * resultText.length(), 150);
  }
-
 }
--
1.7.5.3.964.g497db.dirty