二維碼的產生,二維碼產生

來源:互聯網
上載者:User

二維碼的產生,二維碼產生

package liupeng;import java.io.File;import org.json.JSONException;import org.json.JSONObject;public class Test {/** * 描述:二維碼的產生 * @author liupeng * @param args * @throws JSONException  */public static void main(String[] args) throws JSONException {JSONObject obj = new JSONObject();obj.put("name", "liupeng");obj.put("age", 22);obj.put("school", "[鹽城師範學院]資訊科學與技術學院->軟體工程");//String tomcatRoot = httpRequest.getSession().getServletContext().getRealPath("/SealAndSignImages");//String path = QRCodeOperator.MakeQRCode(tomcatRoot,"劉鵬的二維碼", obj.toString());String path = QRCodeOperator.MakeQRCode("F:"+File.separator,"劉鵬的二維碼", obj.toString());if(path != ""){System.out.println("二維碼內容為:"+obj.toString());}}}package liupeng;import java.awt.image.BufferedImage;import java.io.File;import java.util.HashMap;import java.util.Map;import javax.imageio.ImageIO;import javax.servlet.http.HttpServletRequest;import com.google.zxing.BarcodeFormat;import com.google.zxing.Binarizer;import com.google.zxing.BinaryBitmap;import com.google.zxing.EncodeHintType;import com.google.zxing.LuminanceSource;import com.google.zxing.MultiFormatReader;import com.google.zxing.MultiFormatWriter;import com.google.zxing.Result;import com.google.zxing.common.BitMatrix;import com.google.zxing.common.HybridBinarizer;public class QRCodeOperator {/** * 產生二維碼 * @param name 二維碼檔案名稱(不帶尾碼) * @param content 二維碼內容 * @return 二維碼圖片路徑 */public static String MakeQRCode(String filepath,String name, String content){String retPath = "";try {                 //String content = "120605181003;http://www.cnblogs.com/jtmjx";     //String path = FileOperator.getRootPath();String path = filepath;//httpRequest.getSession().getServletContext().getRealPath("/SealAndSignImages");          MultiFormatWriter multiFormatWriter = new MultiFormatWriter();          Map hints = new HashMap();     hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");     BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 200, 200,hints);     File file1 = new File(path, name+".jpg");     MatrixToImageWriter.writeToFile(bitMatrix, "jpg", file1);     retPath = file1.getAbsolutePath(); } catch (Exception e) {     e.printStackTrace(); }return retPath;}public static void AnalysisQRCode(){try {            MultiFormatReader formatReader = new MultiFormatReader();String filePath = "F:/Users/Administrator/Desktop/testImage/test.jpg";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);Map hints = new HashMap();hints.put(EncodeHintType.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();}}}package liupeng;import com.google.zxing.common.BitMatrix;import javax.imageio.ImageIO;import java.io.File;import java.io.OutputStream;import java.io.IOException;import java.awt.image.BufferedImage;public final class MatrixToImageWriter {  private static final int BLACK = 0xFF000000;  private static final int WHITE = 0xFFFFFFFF;  private MatrixToImageWriter() {}  public static BufferedImage toBufferedImage(BitMatrix matrix) {    int width = matrix.getWidth();    int height = matrix.getHeight();    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    for (int x = 0; x < width; x++) {      for (int y = 0; y < height; y++) {        image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);      }    }    return image;  }  public static void writeToFile(BitMatrix matrix, String format, File file)      throws IOException {    BufferedImage image = toBufferedImage(matrix);    if (!ImageIO.write(image, format, file)) {      throw new IOException("Could not write an image of format " + format + " to " + file);    }  }    public static void writeToStream(BitMatrix matrix, String format, OutputStream stream)      throws IOException {    BufferedImage image = toBufferedImage(matrix);    if (!ImageIO.write(image, format, stream)) {      throw new IOException("Could not write an image of format " + format);    }  }}


注意:需要匯入org.json.jar和zxing-core-2.0.jar


二維碼怎產生

基礎知識
首先,我們先說一下二維碼一共有40個尺寸。官方叫版本Version。Version 1是21 x 21的矩陣,Version 2是 25 x 25的矩陣,Version 3是29的尺寸,每增加一個version,就會增加4的尺寸,公式是:(V-1)*4 + 21(V是版本號碼) 最高Version 40,(40-1)*4+21 = 177,所以最高是177 x 177 的正方形。
下面我們看看一個二維碼的範例:

定位元影像案

Position Detection Pattern是定位元影像案,用於標記二維碼的矩形大小。這三個定位元影像案有白邊叫Separators for Postion Detection Patterns。之所以三個而不是四個意思就是三個就可以標識一個矩形了。

Timing Patterns也是用於定位的。原因是二維碼有40種尺寸,尺寸過大了後需要有根標準線,不然掃描的時候可能會掃歪了。

Alignment Patterns 只有Version 2以上(包括Version2)的二維碼需要這個東東,同樣是為了定位用的。
功能性資料

Format Information 存在於所有的尺寸中,用於存放一些格式化資料的。

Version Information 在 >= Version 7以上,需要預留兩塊3 x 6的地區存放一些版本資訊。
資料碼和錯誤修正碼

除了上述的那些地方,剩下的地方存放 Data Code 資料碼 和 Error Correction Code 錯誤修正碼。
資料編碼
我們先來說說資料編碼。QR碼支援如下的編碼:
Numeric mode 數字編碼,從0到9。如果需要編碼的數位個數不是3的倍數,那麼,最後剩下的1或2位元會被轉成4或7bits,則其它的每3位元字會被編成 10,12,14bits,編成多長還要看二維碼的尺寸(下面有一個表Table 3說明了這點)
Alphanumeric mode 字元編碼。包括 0-9,大寫的A到Z(沒有小寫),以及符號$ % * + – . / : 包括空格。這些字元會映射成一個字元索引表。如下所示:(其中的SP是空格,Char是字元,Value是其索引值) 編碼的過程是把字元兩兩分組,然後轉成下表的45進位,然後轉成11bits的二進位,如果最後有一個落單的,那就轉成6bits的二進位。而編碼模式和字元的個數需要根據不同的Version尺寸編成9, 11或13個二進位(如下表中Table 3)

Byte mode, 位元組編碼,可以是0-255的ISO-8859-1字元。有些二維碼的掃描器可以自動檢測是否是UTF-8的編碼。
Kanji mode 這是日文編碼,也是雙位元組編碼。同樣,也可以用於中文編碼。日文和漢字的編碼會減去一個值。如:在0X8140 to 0X9FFC中的字元會減去8140,在0XE040到0XEBBF中的字元要減去0XC140,然後把結果前兩個16進位位拿出來乘以0XC0,然後再加上後兩個16進位位,最後轉成13bit的編碼。如樣本:

Extended Channel Interpretation (ECI) mode 主要用於特殊的字元集。並不是所有的掃描器都支援這種編碼。
Structured Append mode 用於混合編碼,也就是說,這個二維碼中包含了多種編碼格式。
FNC1 mode 這種編碼方式主要是給一些特殊的工業或行業用的。比如GS1條碼之類的。
簡單起見,後面三種不會在本文 中討論。
下面兩張表中,

......餘下全文>>
 
二維碼怎產生

基礎知識
首先,我們先說一下二維碼一共有40個尺寸。官方叫版本Version。Version 1是21 x 21的矩陣,Version 2是 25 x 25的矩陣,Version 3是29的尺寸,每增加一個version,就會增加4的尺寸,公式是:(V-1)*4 + 21(V是版本號碼) 最高Version 40,(40-1)*4+21 = 177,所以最高是177 x 177 的正方形。
下面我們看看一個二維碼的範例:

定位元影像案

Position Detection Pattern是定位元影像案,用於標記二維碼的矩形大小。這三個定位元影像案有白邊叫Separators for Postion Detection Patterns。之所以三個而不是四個意思就是三個就可以標識一個矩形了。

Timing Patterns也是用於定位的。原因是二維碼有40種尺寸,尺寸過大了後需要有根標準線,不然掃描的時候可能會掃歪了。

Alignment Patterns 只有Version 2以上(包括Version2)的二維碼需要這個東東,同樣是為了定位用的。
功能性資料

Format Information 存在於所有的尺寸中,用於存放一些格式化資料的。

Version Information 在 >= Version 7以上,需要預留兩塊3 x 6的地區存放一些版本資訊。
資料碼和錯誤修正碼

除了上述的那些地方,剩下的地方存放 Data Code 資料碼 和 Error Correction Code 錯誤修正碼。
資料編碼
我們先來說說資料編碼。QR碼支援如下的編碼:
Numeric mode 數字編碼,從0到9。如果需要編碼的數位個數不是3的倍數,那麼,最後剩下的1或2位元會被轉成4或7bits,則其它的每3位元字會被編成 10,12,14bits,編成多長還要看二維碼的尺寸(下面有一個表Table 3說明了這點)
Alphanumeric mode 字元編碼。包括 0-9,大寫的A到Z(沒有小寫),以及符號$ % * + – . / : 包括空格。這些字元會映射成一個字元索引表。如下所示:(其中的SP是空格,Char是字元,Value是其索引值) 編碼的過程是把字元兩兩分組,然後轉成下表的45進位,然後轉成11bits的二進位,如果最後有一個落單的,那就轉成6bits的二進位。而編碼模式和字元的個數需要根據不同的Version尺寸編成9, 11或13個二進位(如下表中Table 3)

Byte mode, 位元組編碼,可以是0-255的ISO-8859-1字元。有些二維碼的掃描器可以自動檢測是否是UTF-8的編碼。
Kanji mode 這是日文編碼,也是雙位元組編碼。同樣,也可以用於中文編碼。日文和漢字的編碼會減去一個值。如:在0X8140 to 0X9FFC中的字元會減去8140,在0XE040到0XEBBF中的字元要減去0XC140,然後把結果前兩個16進位位拿出來乘以0XC0,然後再加上後兩個16進位位,最後轉成13bit的編碼。如樣本:

Extended Channel Interpretation (ECI) mode 主要用於特殊的字元集。並不是所有的掃描器都支援這種編碼。
Structured Append mode 用於混合編碼,也就是說,這個二維碼中包含了多種編碼格式。
FNC1 mode 這種編碼方式主要是給一些特殊的工業或行業用的。比如GS1條碼之類的。
簡單起見,後面三種不會在本文 中討論。
下面兩張表中,

......餘下全文>>
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.