二维码是国际标准,由日本某公司发明,并保留版权,免费让全世界使用,目前在中国金融支付领域大放异彩。


条码的联合发明人诺曼·约瑟夫·伍德兰德(Norman Joseph Woodland)于上世纪70年代发明了条形码,

这一技术的发明几乎对全球商业活动产生了一场革命,并为消费者在超市的购物节约了大量时间。日前在自己位于

新泽西的家中不幸去世,享年91岁。


二维码和条码的生成使用 zxing,zxing 是开源的条码及二维码生成框架,https://github.com/zxing/zxing/ 免费

获取,目前版本 ver 3.3.3。


以下是测试生成的代码,内容将保存在 c:\temp\a.png 和 c:\temp\b.png 两个图片文件内。

 
/*
 * 2019-2-20
 * 测试 zxing 3.3.3 二维码和条码生成
 */
 
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Hashtable;
 
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
 
public class WriteQRCode
{
 
  public static void main(String[] args)
  {
    int width = 200;
    int height = 200;
 
    // 写 二维码
    TestWriteRCode("c:/temp/a.png", BarcodeFormat.QR_CODE, "二维码文字信息, Hello world", width, height);
 
    // 写条码
    height = 50;
    TestWriteRCode("c:/temp/b.png", BarcodeFormat.CODE_128, "ABC123456abc", width, height);
  }
 
  /**
   * 将字符串信息写入 QRCode
   * 
   * @param fileName
   *          指定文件名
   * @param strContents
   *          写入的内容
   * @param width
   *          尺寸宽
   * @param height
   *          尺寸高
   */
  public static void TestWriteRCode(String fileName, BarcodeFormat typeCode, String strContents, int width, int height)
  {
    Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
    // 字符集
    hints.put(EncodeHintType.CHARACTER_SET, "GBK");// Constant.CHARACTER);
    // 容错质量
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
 
    try
    {
      // 尺寸
      BitMatrix bitMatrix = new MultiFormatWriter().encode(strContents, typeCode, width, height, hints);
      BufferedOutputStream buffer = null;
      buffer = new BufferedOutputStream(new FileOutputStream(fileName));
      // ok
      MatrixToImageWriter.writeToStream(bitMatrix, "png", new FileOutputStream(new File(fileName)));
      buffer.close();
    }
    catch (WriterException e)
    {
      e.printStackTrace();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
 
  }
}

image.png

image.png

生成成功将得到两个 png 文件。


以下是读取 c:\temp\a.png 和 c:\temp\b.png 内的条码及二维码。


/*
 * 2019-2-20
 * 测试 zxing 3.3.3 二维码和条码读取
 */
 
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
 
import javax.imageio.ImageIO;
 
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Reader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.ImageReader;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.multi.GenericMultipleBarcodeReader;
import com.google.zxing.multi.MultipleBarcodeReader;
 
public class ReadCode
{
  private static final Map<DecodeHintType, Object> HINTS;
  private static final Map<DecodeHintType, Object> HINTS_PURE;
 
  static
  {
    HINTS = new EnumMap<>(DecodeHintType.class);
    HINTS.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
    HINTS.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.allOf(BarcodeFormat.class));
    HINTS_PURE = new EnumMap<>(HINTS);
    HINTS_PURE.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
  }
 
  public static void main(String[] args)
  {
    BufferedImage image = null;
    try
    {
      image = ImageIO.read(new File("c:/temp/a.png"));
      ProcessImage(image);
 
      image = ImageIO.read(new File("c:/temp/b.png"));
      ProcessImage(image);
    }
    catch (IOException e)
    {
    }
 
  }
 
  private static void ProcessImage(BufferedImage image)
  {
    LuminanceSource source = new BufferedImageLuminanceSource(image);
    BinaryBitmap bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
    Collection<Result> results = new ArrayList<>(1);
 
    try
    {
 
      Reader reader = new MultiFormatReader();
      ReaderException savedException = null;
      try
      {
        // Look for multiple barcodes
        MultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(reader);
        Result[] theResults = multiReader.decodeMultiple(bitmap, HINTS);
        if (theResults != null)
        {
          results.addAll(Arrays.asList(theResults));
        }
      }
      catch (ReaderException re)
      {
        savedException = re;
      }
 
      if (results.isEmpty())
      {
        try
        {
          // Look for pure barcode
          Result theResult = reader.decode(bitmap, HINTS_PURE);
          if (theResult != null)
          {
            results.add(theResult);
          }
        }
        catch (ReaderException re)
        {
          savedException = re;
        }
      }
 
      if (results.isEmpty())
      {
        try
        {
          // Look for normal barcode in photo
          Result theResult = reader.decode(bitmap, HINTS);
          if (theResult != null)
          {
            results.add(theResult);
          }
        }
        catch (ReaderException re)
        {
          savedException = re;
        }
      }
 
      if (results.isEmpty())
      {
        try
        {
          // Try again with other binarizer
          BinaryBitmap hybridBitmap = new BinaryBitmap(new HybridBinarizer(source));
          Result theResult = reader.decode(hybridBitmap, HINTS);
          if (theResult != null)
          {
            results.add(theResult);
          }
        }
        catch (ReaderException re)
        {
          savedException = re;
        }
      }
 
      if (results.isEmpty())
      {
        try
        {
          throw savedException == null ? NotFoundException.getNotFoundInstance() : savedException;
        }
        catch (FormatException | ChecksumException e)
        {
          // log.info(e.toString());
        }
        catch (ReaderException e)
        { // Including NotFoundException
          // log.info(e.toString());
        }
        return;
      }
 
      for (Result result : results)
      {
        System.out.println(result.getText());
      }
 
    }
    catch (RuntimeException re)
    {
      // Call out unexpected errors in the log clearly
      // log.log(Level.WARNING, "Unexpected exception from library", re);
    }
  }
 
}

image.png

运行读取测试程序,将输出相应的内容。


这里顺便提一下,若二维码或者条码在一个含有表格、文字的富文本文档转换的图片中,也是可以被识别出来的,但会略微消耗一点时间。

————————————————

版权声明:本文为CSDN博主「___NULL」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/joyous/article/details/87748303