title: scanning more than one barcode with zxing in java
body: <p>I need to read pdf417 barcodes from tiffs. There is usually more than one barcode on the image-</p>
  
  <p>This is my code:</p>
  
  <pre><code>InputStream in = null;
          BufferedImage bfi = null;
          File[] files = new File(DIR).listFiles();
  
          for (int i = 0; i &lt; files.length; i++) {
              if (files[i].isFile()) {
                  try {
                      System.out.println(files[i].getName());
                      in = new FileInputStream(files[i]);
                      bfi = ImageIO.read(in);
                  } catch (FileNotFoundException e) {
                      e.printStackTrace();
                  } catch (IOException e) {
                      e.printStackTrace();
                  } finally {
                      if (in != null) {
                          try {
                              in.close();
                          } catch (IOException e) {
                              e.printStackTrace();
                          }
                      }
                  }
  
                  if (bfi != null) {
                      LuminanceSource ls = new BufferedImageLuminanceSource(bfi);
                      BinaryBitmap bmp = new BinaryBitmap(new HybridBinarizer(ls));
                      Reader reader = new MultiFormatReader();
                      Result result = null;
  
                      Hashtable&lt;DecodeHintType, Object&gt; decodeHints = new Hashtable&lt;DecodeHintType, Object&gt;();
                      decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
  
                      try {
                          result = reader.decode(bmp, decodeHints);
                      } catch (NotFoundException e) {
                          e.printStackTrace();
                      } catch (ChecksumException e) {
                          e.printStackTrace();
                      } catch (FormatException e) {
                          e.printStackTrace();
                      }
                      System.out.println(result.getBarcodeFormat());
                      System.out.println("Text " + result.getText());
                      System.out
                              .println("-------------------------------------------------------");
  
                  } else {
                      System.out.println("No Buffered Image for "
                              + files[i].getName());
                  }
              }
  
          }
  </code></pre>
  
  <p>This works sometimes but sometimes it doesn't and the result is null.</p>
  
  <p>I looked at the javadoc of zxing and found a GenericMultipleBarcodeReader. 
  I tried to use in in my code but am doing it wrong because I get a NullPointerException:</p>
  
  <pre><code>Reader reader = new MultiFormatReader();
                      GenericMultipleBarcodeReader greader = new GenericMultipleBarcodeReader(reader);
                      Result[] result = null;
  
                      Hashtable&lt;DecodeHintType, Object&gt; decodeHints = new Hashtable&lt;DecodeHintType, Object&gt;();
                      decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
  
                      try {
                          result = greader.decodeMultiple(bmp, decodeHints);
                      } catch (NotFoundException e) {
                          e.printStackTrace();
                      }
  
                      for (int j = 0; j &lt; result.length; j++) {
                          System.out.println(result[j].getBarcodeFormat());
                          System.out.println("Text " + result[j].getText());
                      }
  
  
  Exception in thread "main" java.lang.NullPointerException
      at com.google.zxing.multi.GenericMultipleBarcodeReader.translateResultPoints(GenericMultipleBarcodeReader.java:163)
      at com.google.zxing.multi.GenericMultipleBarcodeReader.doDecodeMultiple(GenericMultipleBarcodeReader.java:96)
      at com.google.zxing.multi.GenericMultipleBarcodeReader.doDecodeMultiple(GenericMultipleBarcodeReader.java:148)
      at com.google.zxing.multi.GenericMultipleBarcodeReader.decodeMultiple(GenericMultipleBarcodeReader.java:65)
      at barcode.ZXingTest.main(ZXingTest.java:77)
  </code></pre>
  
  <p>So the question is: Is it better to use the GenericMultipleBarcodeReader (or some other class) to scan multiple barcodes on an image and if so, how do I have to implement that?</p>
  
  <p>UPDATE:</p>
  
  <pre><code>for (int i = 0; i &lt; files.length; i++) {
              try (BufferedInputStream bfin = new BufferedInputStream(
                      new FileInputStream(files[i]))) {
                  dateiname = files[i].getName();
  
                  bfi = ImageIO.read(bfin);
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }
  
              if (bfi != null) {
                  LuminanceSource ls = new BufferedImageLuminanceSource(bfi);
                  BinaryBitmap bmp = new BinaryBitmap(new HybridBinarizer(ls));
  
                  Reader reader = new MultiFormatReader();
                  GenericMultipleBarcodeReader greader = new GenericMultipleBarcodeReader(
                          new ByQuadrantReader(reader));
                  Result[] result = null;
  
                  Hashtable&lt;DecodeHintType, Object&gt; decodeHints = new Hashtable&lt;DecodeHintType, Object&gt;();
                  decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
  
                  try {
                      result = greader.decodeMultiple(bmp, decodeHints);
                  } catch (NotFoundException e) {
                      e.printStackTrace();
                      System.out.println("No result");
                      System.out.println("+++++++++++++++++++++++++++++++");
                  }
                  if (result != null) {
                      for (int j = 0; j &lt; result.length; j++) {
                          System.out.println(result[j].getText());
                          System.out.println("+++++++++++++++++++++++++++++++");
                      } 
                  }
  
              } else {
                  System.out.println("No Buffered Image for "
                          + files[i].getName());
              }
  
          }
  </code></pre>
  
  <p>If I try it without the ByQuadrantReader, I get the same NullPointerException.
  The way I'm doing it , result.length is sometimes 1 (returning one String) and sometimes I get a NotFoundException.</p>
  
  <p>I hope it's not a dumb fault in my code that I don't see...</p>
  
  <p>2nd EDIT:</p>
  
  <pre><code>Exception in thread "main" java.lang.NullPointerException
      at com.google.zxing.multi.GenericMultipleBarcodeReader.doDecodeMultiple(GenericMultipleBarcodeReader.java:109)
      at com.google.zxing.multi.GenericMultipleBarcodeReader.doDecodeMultiple(GenericMultipleBarcodeReader.java:148)
      at com.google.zxing.multi.GenericMultipleBarcodeReader.decodeMultiple(GenericMultipleBarcodeReader.java:65)
      at barcode.ZXingTestMulti.main(ZXingTestMulti.java:86)
  </code></pre>
  
  <p>3rd EDIT:</p>
  
  <pre><code>current version of code:
  
  public static void main(final String[] args) {
  
          BufferedImage bfi = null;
          File[] files = new File(DIR).listFiles();
          int counttiffs = 0;
          String filename = null;
          TreeMap&lt;String, Exception&gt; errormap = new TreeMap&lt;String, Exception&gt;();
          int onebarcode = 0;
          int twobarcodes = 0;
          int threebarcodes = 0;
  
          for (int i = 0; i &lt; files.length; i++) {
              if (files[i].isFile()) {
                  try (BufferedInputStream bfin = new BufferedInputStream(
                          new FileInputStream(files[i]))) {
                      filename = files[i].getName();
  
                      bfi = ImageIO.read(bfin);
                  } catch (FileNotFoundException e) {
                      e.printStackTrace();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
  
                  if (bfi != null) {
                      LuminanceSource ls = new BufferedImageLuminanceSource(bfi);
                      BinaryBitmap bmp = new BinaryBitmap(new HybridBinarizer(ls));
  
                      Reader reader = new MultiFormatReader();
                      GenericMultipleBarcodeReader greader = new GenericMultipleBarcodeReader(
                              reader);
                      Result[] result = null;
  
                      Hashtable&lt;DecodeHintType, Object&gt; decodeHints = new Hashtable&lt;DecodeHintType, Object&gt;();
                      decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
  
                      try {
                          result = greader.decodeMultiple(bmp, decodeHints);
                      } catch (NotFoundException e) {
                          errormap.put(filename, e);
                      } catch (NullPointerException e) {
                          errormap.put(filename, e);
                      }
                      if (result != null) {
                          switch (result.length) {
                              case 1:
                                  onebarcode++;
                                  break;
                              case 3:
                                  threebarcodes++;
                                  break;
                              default:
                                  twobarcodes++;
  
                          }
                          try (BufferedWriter bfwr = new BufferedWriter(
                                  new FileWriter(FILE, true))) {
                              bfwr.write(filename + ": number of barcodes found = "
                                      + result.length);
                              bfwr.newLine();
                              for (int j = 0; j &lt; result.length; j++) {
                                  bfwr.write(result[j].getText());
                              }
                              bfwr.newLine();
                              bfwr.write("---------------------------------------------------------");
                              bfwr.newLine();
                              counttiffs++;
                          } catch (IOException e) {
                              e.printStackTrace();
                          }
  
                      }
  
                  }
                  else {
                      System.out.println("No Buffered Image for "
                              + files[i].getName());
                  }
              }
          }
  </code></pre>
  
  <p>I'm using snapshots 3.1.1 of core and javase.</p>
  
  <p>As you see, I need to catch a NPE:</p>
  
  <pre><code>java.lang.NullPointerException
      at com.google.zxing.multi.GenericMultipleBarcodeReader.translateResultPoints(GenericMultipleBarcodeReader.java:163)
      at com.google.zxing.multi.GenericMultipleBarcodeReader.doDecodeMultiple(GenericMultipleBarcodeReader.java:96)
      at com.google.zxing.multi.GenericMultipleBarcodeReader.doDecodeMultiple(GenericMultipleBarcodeReader.java:148)
      at com.google.zxing.multi.GenericMultipleBarcodeReader.decodeMultiple(GenericMultipleBarcodeReader.java:65)
      at zBarcodes_Test.ZXingTestMulti.main(ZXingTestMulti.java:72)
  </code></pre>
  
  <p>It's the same as the first one. After your first commit, I got a NPE on a different line, but now either I'm using the wrong dependency or it happened again.</p>
  
  <p>And the other thing is: I scanned about 2.500 tiff-files, each with two pdf417 barcodes on them, some a little tilted and some not in perfect quality (meaning some pixles are white instead of black). I get a total of 1644 errors, either caused by a NotFoundException or NullPointer Exception. And of the 948 files scanned successfully, with 218 result.length is 1 (and it only found one barcode) and with 68, result.length is 3 (but it scanned 2 barcodes as it should).</p>
  
  <p>In your experience, how sensible is zxing when barcodes are not perfetcly straight and have little errors on the edges, where pixles have not been printed perfectly?</p>