2021SC@SDUSC
目錄
- 一、demo引入
- 二、編碼關鍵類詳解
- 2.1 Writer
- 2.2 EncodeHintType
- 2.3 WriterException
- 2.4 MultiFormatWriter
- 三、生成二維碼圖片
- 3.1 Java SE平臺
- 3.2 Android 平臺
- 小結
- 參考資料
前言:Zxing是一個開源Java類別庫用于決議多種格式的條形碼和二維碼,本篇主要分析Zxing的二維碼是如何進行編碼生成的,博客分析了Zxing可以支持的多種二維碼/條形碼編碼生成的一般步驟,即各種條碼編碼的共用關鍵類,在后續的代碼分析中,我將分別對不同的二維碼/條形碼的編碼演算法進行分析,
一、demo引入
在上篇博客的demo中可以看出,二維碼的生成,是從下面這個函式開始的:
BitMatrix encode = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
BitMatrix的matrix物件包含了一個二維碼的所有資訊,用戶得到它之后就可以繪制二維碼了,
MultiFormatWriter是一個factory類,MultiFormatWriter.encode用來對不同的碼格式的編碼方法(write)進行尋找,實際生成二維碼的作業是在各個不同碼的Encoder.encoder方法中實作的,
二、編碼關鍵類詳解
2.1 Writer
Writer類是生成條形碼影像的所有物件的基類, 在實作類可以生成二維碼、條形碼等其他圖形編碼,共有兩個方法,都是用于生成二維碼:
public interface Writer {
BitMatrix encode(String contents, BarcodeFormat format, int width, int height)
throws WriterException;
BitMatrix encode(String contents,
BarcodeFormat format,
int width,
int height,
Map<EncodeHintType,?> hints)
throws WriterException;
}
方法引數說明如下:
| 引數 | 說明 |
|---|---|
| String contents | 二維碼/條形碼中要編碼的內容 |
| BarcodeFormat format | 要生成的二維碼/條形碼格式 |
| int width | 以像素為單位的首選寬度 |
| int height | 以像素為單位的首選高度 |
| Map<EncodeHintType,?> hints | 提示向編碼器提供其他引數 |
從上面可以看出,除了我們常規認為的編碼需要內容之外,還有其他不少的資訊,如編碼的方式,編碼的首選寬高度(首選的意思是:生成的圖片的參考尺寸,如二維碼是正方形,如果給一個矩形,則會留白;條形碼為矩形,如果給一個正方形,則也會留白),
2.2 EncodeHintType
由2.1中encode方法可以看出,編碼包括引數Map<EncodeHintType, ?>,key為EncodeHintType列舉,此列舉是一組提示,您可以傳遞給撰寫者以指定其行為,列舉引數如下:
| 引數 | 說明 |
|---|---|
| ERROR_CORRECTION | 容錯率,指定容錯等級,例如二維碼中使用的ErrorCorrectionLevel, Aztec使用Integer,分為四個等級:L/M/Q/H, 等級越高,容錯率越高,識別速度降低,例如一個角被損壞,容錯率高的也許能夠識別出來,通常為H |
| CHARACTER_SET | 編碼集,通常有中文,設定為 utf-8 |
| DATA_MATRIX_SHAPE | 指定生成的資料矩陣的形狀,型別為SymbolShapeHint |
| MIN_SIZE | 指定最小二維碼/條形碼大小 |
| MAX_SIZE | 指定最大二維碼/條形碼大小 |
| MARGIN | 生成條碼的時候使用,指定邊距,單位像素,受格式的影響,型別Integer, 或String代表的數字型別,默認為4 |
| PDF417_COMPACT | 指定是否使用PDF417緊湊模式,型別Boolean |
| PDF417_COMPACTION | 指定PDF417的緊湊型別 |
| PDF417_DIMENSIONS | 指定PDF417的最大最小行列數 |
| AZTEC_LAYERS | aztec編碼相關 |
| QR_VERSION | 指定二維碼版本,版本越高越復雜,反而不容易決議 |
| QR_MASK_PATTERN | 指定要使用的二維碼掩碼圖案,默認情況下,代碼將自動選擇最佳遮罩圖案, |
| GS1_FORMAT | 指定是否應將資料編碼為GS1標準 |
| FORCE_CODE_SET | 強制使用哪種編碼,目前僅用于Code-128代碼集 |
2.3 WriterException
除上述外,我們還可以看到,在類Writer的兩個生成方法中,都有例外處理throws WriterException,WriterException是一個基類,涵蓋使用Writer框架編碼條形碼時可能出現的例外范圍,
public final class WriterException extends Exception {
public WriterException() {}
public WriterException(String message) {
super(message);
}
public WriterException(Throwable cause) {
super(cause);
}
}
2.4 MultiFormatWriter
MultiFormatWriter是一個工廠類,它為請求的編碼格式查找適當的Writer子類,并使用提供的內容對二維碼/條形碼進行編碼,由下面代碼可以看出Zxing所支持的二維碼、條形碼的型別,這些型別在列舉類BarcodeFormat也可以看到,
public final class MultiFormatWriter implements Writer {
@Override
public BitMatrix encode(String contents,
BarcodeFormat format,
int width,
int height) throws WriterException {
return encode(contents, format, width, height, null);
}
@Override
public BitMatrix encode(String contents,
BarcodeFormat format,
int width, int height,
Map<EncodeHintType,?> hints) throws WriterException {
Writer writer;
switch (format) {
case EAN_8: writer = new EAN8Writer();break;
case UPC_E:writer = new UPCEWriter();break;
case EAN_13:writer = new EAN13Writer();break;
case UPC_A:writer = new UPCAWriter();break;
case QR_CODE:writer = new QRCodeWriter();break;
case CODE_39:writer = new Code39Writer();break;
case CODE_93:writer = new Code93Writer();break;
case CODE_128:writer = new Code128Writer();break;
case ITF:writer = new ITFWriter();break;
case PDF_417:writer = new PDF417Writer();break;
case CODABAR:writer = new CodaBarWriter();break;
case DATA_MATRIX:writer = new DataMatrixWriter();break;
case AZTEC:writer = new AztecWriter();break;
default:
throw new IllegalArgumentException("No encoder available for format " + format);
}
return writer.encode(contents, format, width, height, hints);
}
}
三、生成二維碼圖片
通過上述類及其方法,選擇所需的編碼方式進行編碼后,得到的是一個BitMatrix, 如果需要顯示出來則要根據不同平臺來處理,
3.1 Java SE平臺
1、將BitMatrix轉換成BufferedImage,其方法為:
public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config)
其中,BitMatrix是二維碼的描述物件;MatrixToImageConfig是二維碼轉換成BufferedImage的配置引數,其物件中只有兩個域onColor和offColor, 這樣的配置表示生成的BufferedImage用兩種顏色來表示二維碼上的開關,
2、將BitMatrix轉換成圖片檔案,其方法為:
public static boolean write(RenderedImage im, String formatName, File output) throws IOException
其中,RenderedImage im實作了RenderedImage介面,String formatName是圖片檔案格式,通常使用 png,File output是圖片檔案,
上面兩步結合起來就直接將BitMatrix轉換成圖片檔案,即:
public static void writeToPath(BitMatrix matrix, String format, Path file, MatrixToImageConfig config) throws IOException
3.2 Android 平臺
類似的,在Android中也是先將BitMatrix轉換成Bitmap, 然后再寫入到檔案中,
1、將BitMatrix轉換成Bitmap,分為三步:
①創建一個一維int陣列存放轉換后的顏色值
②根據BitMatrix中的位值設定相應像素點的顏色值
③創建一個“相同”大小的Bitmap, 使用代表顏色的陣列為其賦值(注意:顏色值中前兩位默認為00, 表示透明)
2、Bitmap寫入到檔案中:
Bitmap.compress(CompressFormat format, int quality, OutputStream stream)
具體細節不再介紹,在下面參考資料鏈接中都有,這并不是我分析代碼的重點,因此不再贅述,
小結
本文分析了Zxing支持的各種二維碼、條形碼編碼的公用方法,是接下來具體分析各種編碼演算法的前提,也是理解具體編碼演算法的基礎,
參考資料
ZXing的應用
Zxing生成二維碼思路和原始碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/310027.html
標籤:其他
