2012-02-09 73 views
1

我試圖使用ZXing庫開發解碼QR碼的Java項目。但是,一些包含QR碼的圖像無法通過運行我的項目來解碼,但這些與Online ZXing解碼器一起工作正常。我只是好奇ZXing發佈的版本和他們用於在線解碼器的版本是一樣的嗎?或者他們調整了在線版本。由於這種困惑,我正在拉我的頭髮。發佈ZXing 2.0與在線ZXing解碼器不同嗎?

public class Validator implements IValidator { 
    private static Logger logger = Logger.getLogger(Validator.class); 
    private BufferedImage currentImage; 
    private String resultText; 
    private float moduleSize; 
    private ResultPoint[] patternCenters; 
    private int blockSizePower; 

    public Validator(BufferedImage imageFile) { 
     this.currentImage = imageFile; 
     setLuminanceThreshold(3); //default value used by validator 
    } 

    public Validator(File imageFile) { 
     // take input image file and store in a BufferedImage variable 
     try { 
      currentImage = ImageIO.read(imageFile); 
     } catch (IOException e) { 
      logger.error("Image cannot be opened. There is no such image file. ", e); 
     } 
    } 


    /** 
    * <p>Validating the QR code</p> 
    * 
    * @return true if the QR code can be decoded 
    */ 
    @Override 
    public boolean validateQRCode() { 
     return validateQRCode(null); 
    } 

    public boolean validateQRCode(Hashtable outValues) { 
     return validateQRCode(outValues, true); 
    } 

    // if localLuminanceCheck == true then call HybridBinarizer, otherwise call GlobalHistogramBinarizer 
    public boolean validateQRCode(Hashtable outValues, boolean localLuminanceCheck) 
    { 
     return validateQRCode(outValues, true, false); 
    } 

    public boolean validateQRCode(Hashtable outValues, boolean localLuminanceCheck, boolean scale) { 
     if (scale) 
     { 
      try { 
       this.currentImage = Thumbnails.of(currentImage).size(275, 275).asBufferedImage(); 

      } catch (IOException e) { 
       logger.error("Image cannot be scaled. ", e); 
      } 
     } 

     // finding luminance of the image 
     LuminanceSource lumSource = new BufferedImageLuminanceSource(currentImage); 

     Binarizer qrHB; 
     if (!localLuminanceCheck) { 
      qrHB = new GlobalHistogramBinarizer(lumSource); 
     } else { 
      // creating binary bitmap from Black-White image 
      qrHB = new HybridBinarizer(lumSource); 
      ((HybridBinarizer) qrHB).setBLOCK_SIZE_POWER(blockSizePower); 
     } 
     BinaryBitmap bitmap = new BinaryBitmap(qrHB); 

     try { 
      currentImage = MatrixToImageWriter.toBufferedImage(bitmap.getBlackMatrix()); 
     } catch (NotFoundException e) { 
      logger.error("cannot find any bit matrix.", e); 
     } 

     Hashtable<DecodeHintType, Object> hint = new Hashtable<DecodeHintType, Object>(); 
     hint.put(DecodeHintType.TRY_HARDER, BarcodeFormat.QR_CODE); 

     QRCodeReader QRreader = new QRCodeReader(); 

     try { 
      // decodes the QR code 
      Result result = QRreader.decode(bitmap, hint); 

      resultText = result.getText(); 
      return true; 
     } catch (NotFoundException e) { 
      logger.info("cannot detect any QR code (no enough finder patterns)."); 
      return false; 
     } catch (ChecksumException e) { 
      logger.info("cannot recover the QR code. Too much data errors."); 
      return false; 
     } catch (FormatException e) { 
      logger.info("QR code cannot be decoded."); 
      return false; 
     } catch (FinderPatternNotFoundException e) { 
      // if no Finder Pattern has been found, it may be the color of 
      // QR is inverted. So we invert the QR and try one more time 

      Binarizer invertHB; 
      if (!localLuminanceCheck) { 
       invertHB = new GlobalHistogramBinarizer(lumSource); 
      } else { 
       invertHB = new HybridBinarizer(lumSource); 
       ((HybridBinarizer) invertHB).setBLOCK_SIZE_POWER(blockSizePower); 
      } 

      // get the inverted Black-White matrix 
      BitMatrix invertBlackMatrix = null; 
      try { 
       invertBlackMatrix = invertHB.getBlackMatrix(); 
      } catch (NotFoundException e1) { 
       logger.error(e1); 
      } 

      int invertWidth = currentImage.getWidth(); 
      int invertHeight = currentImage.getHeight(); 

      // flip each bit in the inverted BitMatrix 
      for (int x = 0; x < invertWidth; x++) { 
       for (int y = 0; y < invertHeight; y++) { 
        invertBlackMatrix.flip(x, y); 
       } 
      } 

      currentImage = MatrixToImageWriter.toBufferedImage(invertBlackMatrix); 

      // get luminance source from inverted image 
      lumSource = new BufferedImageLuminanceSource(currentImage); 

      Binarizer afterInvertHB; 
      if (!localLuminanceCheck) { 
       afterInvertHB = new GlobalHistogramBinarizer(lumSource); 

      } else { 
       // creating binary bitmap from Black-White image 
       afterInvertHB = new HybridBinarizer(lumSource); 
       ((HybridBinarizer) afterInvertHB).setBLOCK_SIZE_POWER(blockSizePower); 
      } 
      BinaryBitmap invertBitMap = new BinaryBitmap(afterInvertHB); 

      // decoding inverted QR 
      QRCodeReader invertQRreader = new QRCodeReader(); 

      try { 
       Result invertResult = invertQRreader.decode(invertBitMap, hint); 

       resultText = invertResult.getText(); 

       System.out.println("Out put data is: " + resultText); 

       return true; 
      } catch (NotFoundException e1) { 
       logger.info("cannot detect any QR code (no enough finder patterns)."); 
       return false; 
      } catch (ChecksumException e1) { 
       logger.info("cannot recover the QR code. Too much data errors."); 
       return false; 
      } catch (FormatException e1) { 
       logger.info("QR code cannot be decoded."); 
       return false; 
      } catch (FinderPatternNotFoundException e1) { 
       logger.info("Cannot confirm where all three Finder Patterns are! "); 
       return false; 
      } catch (Exception e1) { 
       logger.error(e1); 
       return false; 
      } 
     } catch (Exception e) { 
      logger.error(e); 
      return false; 
     } 
    } 

} 

回答

0

這不是不同的,它可能是你沒有使用TRY_HARDER模式,或者是不是想這兩個二值化。在線版本將做這些事情。

+0

我已經發布了我的代碼,請看看這個。在包含TRY_HARDER的代碼中,檢查了HybridBinarizer和GlobalHistogramBinarizer。請指出可能導致問題的原因。謝謝 – user1139921 2012-02-09 22:54:49