ZXing解析二维码

ZXing解析二维码

zxing 开发技巧:http://www.csdn.net/tag/zxing/blog

分类: 二维码 java 177人阅读 评论(0) 收藏 举报

  上一篇文件已经说过如何用ZXing进行生成二维码和带图片的二维码,下面说下如何解析二维码

二维码的解析和生成类似,也可以参考google的一个操作类 BufferedImageLuminanceSource类,该类可在google的测试包中找到,另外j2se中也有该类,你可以将该类直接拷贝到源码中使用,你也可以自己写个。

  1. import java.awt.Graphics2D;  
  2. import java.awt.geom.AffineTransform;  
  3. import java.awt.image.BufferedImage;  
  4. import java.awt.image.WritableRaster;  
  5. import com.google.zxing.LuminanceSource;  
  6.   
  7. /** 
  8.  *  
  9.  * 二维码的解析需要借助BufferedImageLuminanceSource类,该类是由Google提供的,可以将该类直接拷贝到源码中使用,当然你也可以自己写个 
  10.  * 解析条形码的基类 
  11.  */  
  12.   
  13. public final class BufferedImageLuminanceSource extends LuminanceSource {  
  14.   
  15.   private static final double MINUS_45_IN_RADIANS = -0.7853981633974483// Math.toRadians(-45.0)  
  16.   
  17.   private final BufferedImage image;  
  18.   private final int left;  
  19.   private final int top;  
  20.   
  21.   private static final boolean EXPLICIT_LUMINANCE_CONVERSION;  
  22.   static {  
  23.     String property = System.getProperty("explicitLuminanceConversion");  
  24.     if (property == null) {  
  25.       property = System.getenv("EXPLICIT_LUMINANCE_CONVERSION");  
  26.     }  
  27.     EXPLICIT_LUMINANCE_CONVERSION = Boolean.parseBoolean(property);  
  28.   }  
  29.   
  30.   public BufferedImageLuminanceSource(BufferedImage image) {  
  31.     this(image, 00, image.getWidth(), image.getHeight());  
  32.   }  
  33.   
  34.   public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {  
  35.     super(width, height);  
  36.   
  37.     if (image.getType() == BufferedImage.TYPE_BYTE_GRAY) {  
  38.       this.image = image;  
  39.     } else {  
  40.       int sourceWidth = image.getWidth();  
  41.       int sourceHeight = image.getHeight();  
  42.       if (left + width > sourceWidth || top + height > sourceHeight) {  
  43.         throw new IllegalArgumentException("Crop rectangle does not fit within image data.");  
  44.       }  
  45.   
  46.       this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);  
  47.   
  48.       if (EXPLICIT_LUMINANCE_CONVERSION) {  
  49.   
  50.         WritableRaster raster = this.image.getRaster();  
  51.         int[] buffer = new int[width];  
  52.         for (int y = top; y < top + height; y++) {  
  53.           image.getRGB(left, y, width, 1, buffer, 0, sourceWidth);  
  54.           for (int x = 0; x < width; x++) {  
  55.             int pixel = buffer[x];  
  56.   
  57.             // see comments in implicit branch  
  58.             if ((pixel & 0xFF000000) == 0) {  
  59.               pixel = 0xFFFFFFFF// = white  
  60.             }  
  61.   
  62.             // .229R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC)  
  63.             buffer[x] =  
  64.                 (306 * ((pixel >> 16) & 0xFF) +  
  65.                  601 * ((pixel >> 8) & 0xFF) +  
  66.                  117 * (pixel & 0xFF) +  
  67.                  0x200) >> 10;  
  68.           }  
  69.           raster.setPixels(left, y, width, 1, buffer);  
  70.         }  
  71.   
  72.       } else {  
  73.   
  74.         // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent  
  75.         // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a  
  76.         // barcode image. Force any such pixel to be white:  
  77.         if (image.getAlphaRaster() != null) {  
  78.           int[] buffer = new int[width];  
  79.           for (int y = top; y < top + height; y++) {  
  80.             image.getRGB(left, y, width, 1, buffer, 0, sourceWidth);  
  81.             boolean rowChanged = false;  
  82.             for (int x = 0; x < width; x++) {  
  83.               if ((buffer[x] & 0xFF000000) == 0) {  
  84.                 buffer[x] = 0xFFFFFFFF// = white  
  85.                 rowChanged = true;  
  86.               }  
  87.             }  
  88.             if (rowChanged) {  
  89.               image.setRGB(left, y, width, 1, buffer, 0, sourceWidth);  
  90.             }  
  91.           }  
  92.         }  
  93.   
  94.         // Create a grayscale copy, no need to calculate the luminance manually  
  95.         this.image.getGraphics().drawImage(image, 00null);  
  96.   
  97.       }  
  98.     }  
  99.     this.left = left;  
  100.     this.top = top;  
  101.   }  
  102.   
  103.   @Override  
  104.   public byte[] getRow(int y, byte[] row) {  
  105.     if (y < 0 || y >= getHeight()) {  
  106.       throw new IllegalArgumentException("Requested row is outside the image: " + y);  
  107.     }  
  108.     int width = getWidth();  
  109.     if (row == null || row.length < width) {  
  110.       row = new byte[width];  
  111.     }  
  112.     // The underlying raster of image consists of bytes with the luminance values  
  113.     image.getRaster().getDataElements(left, top + y, width, 1, row);  
  114.     return row;  
  115.   }  
  116.   
  117.   @Override  
  118.   public byte[] getMatrix() {  
  119.     int width = getWidth();  
  120.     int height = getHeight();  
  121.     int area = width * height;  
  122.     byte[] matrix = new byte[area];  
  123.     // The underlying raster of image consists of area bytes with the luminance values  
  124.     image.getRaster().getDataElements(left, top, width, height, matrix);  
  125.     return matrix;  
  126.   }  
  127.   
  128.   @Override  
  129.   public boolean isCropSupported() {  
  130.     return true;  
  131.   }  
  132.   
  133.   @Override  
  134.   public LuminanceSource crop(int left, int top, int width, int height) {  
  135.     return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);  
  136.   }  
  137.   
  138.   /** 
  139.    * This is always true, since the image is a gray-scale image. 
  140.    * 
  141.    * @return true 
  142.    */  
  143.   @Override  
  144.   public boolean isRotateSupported() {  
  145.     return true;  
  146.   }  
  147.   
  148.   @Override  
  149.   public LuminanceSource rotateCounterClockwise() {  
  150.     int sourceWidth = image.getWidth();  
  151.     int sourceHeight = image.getHeight();  
  152.   
  153.     // Rotate 90 degrees counterclockwise.  
  154.     AffineTransform transform = new AffineTransform(0.0, -1.01.00.00.0, sourceWidth);  
  155.   
  156.     // Note width/height are flipped since we are rotating 90 degrees.  
  157.     BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);  
  158.   
  159.     // Draw the original image into rotated, via transformation  
  160.     Graphics2D g = rotatedImage.createGraphics();  
  161.     g.drawImage(image, transform, null);  
  162.     g.dispose();  
  163.   
  164.     // Maintain the cropped region, but rotate it too.  
  165.     int width = getWidth();  
  166.     return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);  
  167.   }  
  168.   
  169.   @Override  
  170.   public LuminanceSource rotateCounterClockwise45() {  
  171.     int width = getWidth();  
  172.     int height = getHeight();  
  173.   
  174.     int oldCenterX = left + width / 2;  
  175.     int oldCenterY = top + height / 2;  
  176.   
  177.     // Rotate 45 degrees counterclockwise.  
  178.     AffineTransform transform = AffineTransform.getRotateInstance(MINUS_45_IN_RADIANS, oldCenterX, oldCenterY);  
  179.   
  180.     int sourceDimension = Math.max(image.getWidth(), image.getHeight());  
  181.     BufferedImage rotatedImage = new BufferedImage(sourceDimension, sourceDimension, BufferedImage.TYPE_BYTE_GRAY);  
  182.   
  183.     // Draw the original image into rotated, via transformation  
  184.     Graphics2D g = rotatedImage.createGraphics();  
  185.     g.drawImage(image, transform, null);  
  186.     g.dispose();  
  187.   
  188.     int halfDimension = Math.max(width, height) / 2;  
  189.     int newLeft = Math.max(0, oldCenterX - halfDimension);  
  190.     int newTop = Math.max(0, oldCenterY - halfDimension);  
  191.     int newRight = Math.min(sourceDimension - 1, oldCenterX + halfDimension);  
  192.     int newBottom = Math.min(sourceDimension - 1, oldCenterY + halfDimension);  
  193.   
  194.     return new BufferedImageLuminanceSource(rotatedImage, newLeft, newTop, newRight - newLeft, newBottom - newTop);  
  195.   }  
  196.   
  197. }  
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import com.google.zxing.LuminanceSource;

/**
 * 
 * 二维码的解析需要借助BufferedImageLuminanceSource类,该类是由Google提供的,可以将该类直接拷贝到源码中使用,当然你也可以自己写个
 * 解析条形码的基类
 */

public final class BufferedImageLuminanceSource extends LuminanceSource {

  private static final double MINUS_45_IN_RADIANS = -0.7853981633974483; // Math.toRadians(-45.0)

  private final BufferedImage image;
  private final int left;
  private final int top;

  private static final boolean EXPLICIT_LUMINANCE_CONVERSION;
  static {
    String property = System.getProperty("explicitLuminanceConversion");
    if (property == null) {
      property = System.getenv("EXPLICIT_LUMINANCE_CONVERSION");
    }
    EXPLICIT_LUMINANCE_CONVERSION = Boolean.parseBoolean(property);
  }

  public BufferedImageLuminanceSource(BufferedImage image) {
    this(image, 0, 0, image.getWidth(), image.getHeight());
  }

  public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {
    super(width, height);

    if (image.getType() == BufferedImage.TYPE_BYTE_GRAY) {
      this.image = image;
    } else {
      int sourceWidth = image.getWidth();
      int sourceHeight = image.getHeight();
      if (left + width > sourceWidth || top + height > sourceHeight) {
        throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
      }

      this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);

      if (EXPLICIT_LUMINANCE_CONVERSION) {

        WritableRaster raster = this.image.getRaster();
        int[] buffer = new int[width];
        for (int y = top; y < top + height; y++) {
          image.getRGB(left, y, width, 1, buffer, 0, sourceWidth);
          for (int x = 0; x < width; x++) {
            int pixel = buffer[x];

            // see comments in implicit branch
            if ((pixel & 0xFF000000) == 0) {
              pixel = 0xFFFFFFFF; // = white
            }

            // .229R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC)
            buffer[x] =
                (306 * ((pixel >> 16) & 0xFF) +
                 601 * ((pixel >> 8) & 0xFF) +
                 117 * (pixel & 0xFF) +
                 0x200) >> 10;
          }
          raster.setPixels(left, y, width, 1, buffer);
        }

      } else {

        // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent
        // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a
        // barcode image. Force any such pixel to be white:
        if (image.getAlphaRaster() != null) {
          int[] buffer = new int[width];
          for (int y = top; y < top + height; y++) {
            image.getRGB(left, y, width, 1, buffer, 0, sourceWidth);
            boolean rowChanged = false;
            for (int x = 0; x < width; x++) {
              if ((buffer[x] & 0xFF000000) == 0) {
                buffer[x] = 0xFFFFFFFF; // = white
                rowChanged = true;
              }
            }
            if (rowChanged) {
              image.setRGB(left, y, width, 1, buffer, 0, sourceWidth);
            }
          }
        }

        // Create a grayscale copy, no need to calculate the luminance manually
        this.image.getGraphics().drawImage(image, 0, 0, null);

      }
    }
    this.left = left;
    this.top = top;
  }

  @Override
  public byte[] getRow(int y, byte[] row) {
    if (y < 0 || y >= getHeight()) {
      throw new IllegalArgumentException("Requested row is outside the image: " + y);
    }
    int width = getWidth();
    if (row == null || row.length < width) {
      row = new byte[width];
    }
    // The underlying raster of image consists of bytes with the luminance values
    image.getRaster().getDataElements(left, top + y, width, 1, row);
    return row;
  }

  @Override
  public byte[] getMatrix() {
    int width = getWidth();
    int height = getHeight();
    int area = width * height;
    byte[] matrix = new byte[area];
    // The underlying raster of image consists of area bytes with the luminance values
    image.getRaster().getDataElements(left, top, width, height, matrix);
    return matrix;
  }

  @Override
  public boolean isCropSupported() {
    return true;
  }

  @Override
  public LuminanceSource crop(int left, int top, int width, int height) {
    return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);
  }

  /**
   * This is always true, since the image is a gray-scale image.
   *
   * @return true
   */
  @Override
  public boolean isRotateSupported() {
    return true;
  }

  @Override
  public LuminanceSource rotateCounterClockwise() {
    int sourceWidth = image.getWidth();
    int sourceHeight = image.getHeight();

    // Rotate 90 degrees counterclockwise.
    AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);

    // Note width/height are flipped since we are rotating 90 degrees.
    BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);

    // Draw the original image into rotated, via transformation
    Graphics2D g = rotatedImage.createGraphics();
    g.drawImage(image, transform, null);
    g.dispose();

    // Maintain the cropped region, but rotate it too.
    int width = getWidth();
    return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
  }

  @Override
  public LuminanceSource rotateCounterClockwise45() {
    int width = getWidth();
    int height = getHeight();

    int oldCenterX = left + width / 2;
    int oldCenterY = top + height / 2;

    // Rotate 45 degrees counterclockwise.
    AffineTransform transform = AffineTransform.getRotateInstance(MINUS_45_IN_RADIANS, oldCenterX, oldCenterY);

    int sourceDimension = Math.max(image.getWidth(), image.getHeight());
    BufferedImage rotatedImage = new BufferedImage(sourceDimension, sourceDimension, BufferedImage.TYPE_BYTE_GRAY);

    // Draw the original image into rotated, via transformation
    Graphics2D g = rotatedImage.createGraphics();
    g.drawImage(image, transform, null);
    g.dispose();

    int halfDimension = Math.max(width, height) / 2;
    int newLeft = Math.max(0, oldCenterX - halfDimension);
    int newTop = Math.max(0, oldCenterY - halfDimension);
    int newRight = Math.min(sourceDimension - 1, oldCenterX + halfDimension);
    int newBottom = Math.min(sourceDimension - 1, oldCenterY + halfDimension);

    return new BufferedImageLuminanceSource(rotatedImage, newLeft, newTop, newRight - newLeft, newBottom - newTop);
  }

}

操作类:DecodeTest

  1. import java.awt.image.BufferedImage;  
  2. import java.io.File;  
  3. import java.util.Hashtable;  
  4. import javax.imageio.ImageIO;  
  5. import com.google.zxing.Binarizer;  
  6. import com.google.zxing.BinaryBitmap;  
  7. import com.google.zxing.DecodeHintType;  
  8. import com.google.zxing.LuminanceSource;  
  9. import com.google.zxing.MultiFormatReader;  
  10. import com.google.zxing.Result;  
  11. import com.google.zxing.common.HybridBinarizer;  
  12. import com.utils.code.BufferedImageLuminanceSource;  
  13.   
  14. /** 
  15.  * 解析二维码  
  16.  * @author Administrator 
  17.  * 
  18.  */  
  19. public class DecodeHelper {  
  20.       
  21.     public static void main(String[] args) throws Exception {  
  22.          try {   
  23.              MultiFormatReader formatReader = new MultiFormatReader();   
  24.              String filePath = "D:\\new-1.gif"//new.png  
  25.              File file = new File(filePath);   
  26.                
  27.              BufferedImage image = ImageIO.read(file);  
  28.                
  29.              LuminanceSource source = new BufferedImageLuminanceSource(image);   
  30.                
  31.              Binarizer  binarizer = new HybridBinarizer(source);   
  32.                
  33.              BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);   
  34.                
  35.              Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();      
  36.              hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");      
  37.                
  38.              Result result = formatReader.decode(binaryBitmap,hints);   
  39.   
  40.              System.out.println("result = "+ result.toString());   
  41.              System.out.println("resultFormat = "+ result.getBarcodeFormat());   
  42.              System.out.println("resultText = "+ result.getText());   
  43.   
  44.          } catch (Exception e) {   
  45.              e.printStackTrace();   
  46.              }   
  47.     }  
  48. }  
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.utils.code.BufferedImageLuminanceSource;

/**
 * 解析二维码 
 * @author Administrator
 *
 */
public class DecodeHelper {
	
	public static void main(String[] args) throws Exception {
		 try { 
	         MultiFormatReader formatReader = new MultiFormatReader(); 
	         String filePath = "D:\\new-1.gif"; //new.png
	         File file = new File(filePath); 
	         
	         BufferedImage image = ImageIO.read(file);
	         
	         LuminanceSource source = new BufferedImageLuminanceSource(image); 
	         
	         Binarizer  binarizer = new HybridBinarizer(source); 
	         
	         BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer); 
	         
	         Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();    
	         hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");    
	         
	         Result result = formatReader.decode(binaryBitmap,hints); 

	         System.out.println("result = "+ result.toString()); 
	         System.out.println("resultFormat = "+ result.getBarcodeFormat()); 
	         System.out.println("resultText = "+ result.getText()); 

		 } catch (Exception e) { 
	         e.printStackTrace(); 
	         } 
	}
}





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值