前面的一些博文中已經提到了zxing這個開源工具生成和讀取二維碼圖片,僅從學習的角度來看,能夠告一個段落。在實際的生產環境中,應用zxing生成和讀取二維碼,卻存在一些問題: java
爲了解決這些問題,在通過一番折騰後,找到了一個替代的解決方案,使用iText工具生成二維碼圖片,因爲iText沒有提供類讀取二維碼內容,這裏咱們仍然使用zxing,而且特別注意了中文亂碼的問題。下面是代碼: apache
package test; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import javax.imageio.ImageIO; import org.apache.commons.lang.StringUtils; import com.google.zxing.BinaryBitmap; import com.google.zxing.LuminanceSource; import com.google.zxing.MultiFormatReader; import com.google.zxing.Result; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.HybridBinarizer; import com.itextpdf.text.pdf.BarcodePDF417; /** * 功能: 一、提供生成二維碼的服務 二、提供讀取二維碼信息的服務 三、提供生成和讀取二維碼的示例代碼 */ public class TwoDimBarCodeService { /** * 功能:生成二維碼 * @param strInfo 須要存儲的內容 * @param encode 編碼格式,好比:GBK,UTF-8 * @param imgFileExt 生成的圖片格式 * @return byte[] 圖片的byte數組 * @throws Exception */ public byte[] generatePdf417Image(String strInfo, String encode, String imgFileExt) throws Exception { if (StringUtils.isBlank(strInfo)) { throw new Exception("二維條碼的文本信息參數不能爲空!"); } if (StringUtils.isBlank(encode)) { encode = "UTF-8"; } BarcodePDF417 barcodePDF417 = new BarcodePDF417(); barcodePDF417.setText(strInfo.getBytes(encode)); Image pdfImg = barcodePDF417.createAwtImage(Color.black, Color.white); BufferedImage img = new BufferedImage((int) pdfImg.getWidth(null), (int) pdfImg.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics g = img.getGraphics(); g.drawImage(pdfImg, 0, 0, Color.white, null); ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(img, imgFileExt, os); byte[] buffs = os.toByteArray(); os.close(); return buffs; } /** * 功能:從圖片的byte數組中讀取內容 * @param imgBuff 二維碼圖片流的byte[] * @param encode 編碼格式,好比:GBK,UTF-8 * @return * @throws Exception */ public String readInfoFromPdf417Image(byte[] imgBuff, String encode) throws Exception { if (imgBuff == null || imgBuff.length < 1) { throw new Exception("二維條碼的圖片內容不能爲空!"); } InputStream is = new ByteArrayInputStream(imgBuff); BufferedImage image = ImageIO.read(is); LuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result decodedValue = new MultiFormatReader().decode(bitmap); if (decodedValue == null) { return ""; } String resultText = decodedValue.getText(); resultText = StringUtils.trimToEmpty(resultText); byte[] b = resultText.getBytes("ISO-8859-1"); return new String(b, encode); } public static void main(String[] args) throws Exception { TwoDimBarCodeService service = new TwoDimBarCodeService(); String strInfo = "GB0626-2005^JH-201403050005^XX公司^通知^[2014]0005^^關於推廣辦公自動化的通知^祕密5^特急^20140305^^^20140305^^"; byte[] buff = service.generatePdf417Image(strInfo, "GBK", "jpg"); OutputStream os = new FileOutputStream(new File("d:/test.jpg")); os.write(buff); os.flush(); os.close(); System.err.println("文本內容:" + service.readInfoFromPdf417Image(buff, "GBK")); } }
關鍵類:BufferedImage ByteArrayOutputStream 數組
存在的一個問題: 工具
iText生成的圖片也會隨着信息量的變大而變大,解決思路是使用圖像縮放技術,作到圖片的格式固定。 學習