Announcing QR Decoder for ImageJ

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Announcing QR Decoder for ImageJ

Elliott Slaughter
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

Enjoy :-)

--
Elliott Slaughter

"Don't worry about what anybody else is going to do. The best way to predict
the future is to invent it." - Alan Kay
Reply | Threaded
Open this post in threaded view
|

Re: Announcing QR Decoder for ImageJ

dscho
Hi Elliott,

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.

-- snipsnap --
diff -r 9d4c0ddb4272 src/QR_Decoder.java
--- a/src/QR_Decoder.java Sun Jul 31 12:08:11 2011 -0700
+++ b/src/QR_Decoder.java Fri Aug 12 03:32:16 2011 -0700
@@ -1,6 +1,8 @@
 import ij.ImagePlus;
+import ij.Macro;
-import ij.gui.GenericDialog;
 import ij.plugin.filter.PlugInFilter;
+import ij.process.ByteProcessor;
 import ij.process.ImageProcessor;
 import ij.text.TextWindow;
 
@@ -43,32 +45,27 @@
 public class QR_Decoder implements PlugInFilter {
 
  public int setup(String arg, ImagePlus image) {
- return DOES_8G | NO_CHANGES;
+ return DOES_ALL | NO_CHANGES;
  }
 
  public void run(ImageProcessor ip) {
- GenericDialog gd = new GenericDialog("QR Decoder Settings");
- gd.addStringField("Error Results In: ", "FAILED");
- gd.showDialog();
- if (gd.wasCanceled()) {
- return;
- }
- String defaultResultText = gd.getNextString();
-
+ if (!(ip instanceof ByteProcessor))
+ ip = ip.convertToByte(true);
+ else if (!ip.isDefaultLut())
+ ip = ip.convertToRGB().convertToByte(true);
  Reader reader = new QRCodeReader();
  BufferedImage myimg = ip.getBufferedImage();
  LuminanceSource source = new BufferedImageLuminanceSource(myimg);
  BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
- String resultText = defaultResultText;
+ String resultText = "FAILED";
  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.
- } catch (NotFoundException e) {
- } catch (ChecksumException e) {
- } catch (FormatException e) {
+ } catch (Exception e) {
+ Macro.abort();
  }
 
  new TextWindow("QR Code", resultText, 12 * resultText.length(), 150);

fiji-qr.png (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Announcing QR Decoder for ImageJ

Elliott Slaughter
On Fri, Aug 12, 2011 at 3:34 AM, Johannes Schindelin <
[hidden email]> wrote:

> Hi Elliott,
>
> 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?

That is, mind writing a diff for this file? :-)

https://bitbucket.org/elliottslaughter/qr_decoder/src/9d4c0ddb4272/examplemacro.txt

Thanks.

-- snipsnap --

> diff -r 9d4c0ddb4272 src/QR_Decoder.java
> --- a/src/QR_Decoder.java       Sun Jul 31 12:08:11 2011 -0700
> +++ b/src/QR_Decoder.java       Fri Aug 12 03:32:16 2011 -0700
> @@ -1,6 +1,8 @@
>  import ij.ImagePlus;
> +import ij.Macro;
> -import ij.gui.GenericDialog;
>  import ij.plugin.filter.PlugInFilter;
> +import ij.process.ByteProcessor;
>  import ij.process.ImageProcessor;
>  import ij.text.TextWindow;
>
> @@ -43,32 +45,27 @@
>  public class QR_Decoder implements PlugInFilter {
>
>        public int setup(String arg, ImagePlus image) {
> -               return DOES_8G | NO_CHANGES;
> +               return DOES_ALL | NO_CHANGES;
>        }
>
>        public void run(ImageProcessor ip) {
> -               GenericDialog gd = new GenericDialog("QR Decoder
> Settings");
> -               gd.addStringField("Error Results In: ", "FAILED");
> -               gd.showDialog();
> -               if (gd.wasCanceled()) {
> -                       return;
> -               }
> -               String defaultResultText = gd.getNextString();
> -
> +               if (!(ip instanceof ByteProcessor))
> +                       ip = ip.convertToByte(true);
> +               else if (!ip.isDefaultLut())
> +                       ip = ip.convertToRGB().convertToByte(true);
>                Reader reader = new QRCodeReader();
>                BufferedImage myimg = ip.getBufferedImage();
>                LuminanceSource source = new
> BufferedImageLuminanceSource(myimg);
>                BinaryBitmap bitmap = new BinaryBitmap(new
> HybridBinarizer(source));
> -               String resultText = defaultResultText;
> +               String resultText = "FAILED";
>                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.
> -               } catch (NotFoundException e) {
> -               } catch (ChecksumException e) {
> -               } catch (FormatException e) {
> +               } catch (Exception e) {
> +                       Macro.abort();
>                }
>
>                new TextWindow("QR Code", resultText, 12 *
> resultText.length(), 150);




--
Elliott Slaughter

"Don't worry about what anybody else is going to do. The best way to predict
the future is to invent it." - Alan Kay
Reply | Threaded
Open this post in threaded view
|

Re: Announcing QR Decoder for ImageJ

dscho
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
Reply | Threaded
Open this post in threaded view
|

Re: Announcing QR Decoder for ImageJ

Antoinette
Now, 2D barcode reader, including qr code scanning control can be combined within document image system to detect and decode qr code barcode from image or document or text file from any direction no matter the barcode is damaged or not.
Reply | Threaded
Open this post in threaded view
|

Re: Announcing QR Decoder for ImageJ

arronlee
I wonder whether there are any differences between the QR code decoder I am testing these days and those mentioned above. Any suggestion will be appreciated. Thanks in advance.




Best regards,
Arron