我想使用iTextSharp在PDF文件中繪製QR條形碼。如果我使用的是英文文本,條形碼就可以正常解碼,但如果使用的是中文文本,則條形碼將被解碼爲問號。例如,這個字符'測'(\ u6D4B)被解碼爲'?'。我嘗試了所有支持的字符集,但都沒有幫助。
爲了正確編碼中文文本,我應該在iTextSharp中使用QR條形碼的參數組合嗎?如何在iTextSharp生成的QR條碼中編碼中文文本?
回答
iText和iTextSharp顯然不會本地支持這一點,但您可以編寫一些代碼來自行處理。訣竅是讓QR碼解析器只使用任意字節數組而不是字符串。真正好的是iTextSharp代碼已經爲此做好了準備,但是並沒有公開這些功能。不幸的是,許多必需的類是sealed
,所以你不能僅僅繼承它們,你必須重新創建它們。您可以下載整個源代碼並添加這些更改,也可以使用相同的名稱創建單獨的類。 (請檢查許可證以確保您可以執行此操作。)以下更改沒有任何錯誤更正,因此請確保您也這樣做。
,你需要重新創建第一類是iTextSharp.text.pdf.qrcode.BlockPair
只有你需要做出改變是使構造public
而不是internal
。 (如果您要創建自己的代碼並且不修改現有代碼,則只需執行此操作。)
第二類是iTextSharp.text.pdf.qrcode.Encoder
。這是我們將發生最大變化的地方。超載加入Append8BitBytes
看起來像這樣:
static void Append8BitBytes(byte[] bytes, BitVector bits) {
for (int i = 0; i < bytes.Length; ++i) {
bits.AppendBits(bytes[i], 8);
}
}
此方法的字符串版本將文本轉換爲一個字節數組,然後使用上述所以我們只是切割出的中間人。接下來,將一個新的重載添加到接受字節數組而不是字符串的構造函數中。然後,我們將刪除字符串檢測部分並強制系統進入字節模式,否則下面的代碼幾乎是一樣的。
public static void Encode(byte[] bytes, ErrorCorrectionLevel ecLevel, IDictionary<EncodeHintType, Object> hints, QRCode qrCode) {
String encoding = DEFAULT_BYTE_MODE_ENCODING;
// Step 1: Choose the mode (encoding).
Mode mode = Mode.BYTE;
// Step 2: Append "bytes" into "dataBits" in appropriate encoding.
BitVector dataBits = new BitVector();
Append8BitBytes(bytes, dataBits);
// Step 3: Initialize QR code that can contain "dataBits".
int numInputBytes = dataBits.SizeInBytes();
InitQRCode(numInputBytes, ecLevel, mode, qrCode);
// Step 4: Build another bit vector that contains header and data.
BitVector headerAndDataBits = new BitVector();
// Step 4.5: Append ECI message if applicable
if (mode == Mode.BYTE && !DEFAULT_BYTE_MODE_ENCODING.Equals(encoding)) {
CharacterSetECI eci = CharacterSetECI.GetCharacterSetECIByName(encoding);
if (eci != null) {
AppendECI(eci, headerAndDataBits);
}
}
AppendModeInfo(mode, headerAndDataBits);
int numLetters = dataBits.SizeInBytes();
AppendLengthInfo(numLetters, qrCode.GetVersion(), mode, headerAndDataBits);
headerAndDataBits.AppendBitVector(dataBits);
// Step 5: Terminate the bits properly.
TerminateBits(qrCode.GetNumDataBytes(), headerAndDataBits);
// Step 6: Interleave data bits with error correction code.
BitVector finalBits = new BitVector();
InterleaveWithECBytes(headerAndDataBits, qrCode.GetNumTotalBytes(), qrCode.GetNumDataBytes(),
qrCode.GetNumRSBlocks(), finalBits);
// Step 7: Choose the mask pattern and set to "qrCode".
ByteMatrix matrix = new ByteMatrix(qrCode.GetMatrixWidth(), qrCode.GetMatrixWidth());
qrCode.SetMaskPattern(ChooseMaskPattern(finalBits, qrCode.GetECLevel(), qrCode.GetVersion(),
matrix));
// Step 8. Build the matrix and set it to "qrCode".
MatrixUtil.BuildMatrix(finalBits, qrCode.GetECLevel(), qrCode.GetVersion(),
qrCode.GetMaskPattern(), matrix);
qrCode.SetMatrix(matrix);
// Step 9. Make sure we have a valid QR Code.
if (!qrCode.IsValid()) {
throw new WriterException("Invalid QR code: " + qrCode.ToString());
}
}
第三類是iTextSharp.text.pdf.qrcode.QRCodeWriter
,並再次,我們只需要添加一個重載Encode
方法支持字節數組和調用上述新構造函數創建:
public ByteMatrix Encode(byte[] bytes, int width, int height, IDictionary<EncodeHintType, Object> hints) {
ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
if (hints != null && hints.ContainsKey(EncodeHintType.ERROR_CORRECTION))
errorCorrectionLevel = (ErrorCorrectionLevel)hints[EncodeHintType.ERROR_CORRECTION];
QRCode code = new QRCode();
Encoder.Encode(bytes, errorCorrectionLevel, hints, code);
return RenderResult(code, width, height);
}
最後一類是iTextSharp.text.pdf.BarcodeQRCode
這我們再次添加我們的新構造過載:
public BarcodeQRCode(byte[] bytes, int width, int height, IDictionary<EncodeHintType, Object> hints) {
newCode.QRCodeWriter qc = new newCode.QRCodeWriter();
bm = qc.Encode(bytes, width, height, hints);
}
最後一招是確保在調用此包括字節順序標記(BOM),以便解碼器知道正確解碼,在這種情況下UTF-8。
//Create an encoder that supports outputting a BOM
System.Text.Encoding enc = new System.Text.UTF8Encoding(true, true);
//Get the BOM
byte[] bom = enc.GetPreamble();
//Get the raw bytes for the string
byte[] bytes = enc.GetBytes("測");
//Combine the byte arrays
byte[] final = new byte[bom.Length + bytes.Length];
System.Buffer.BlockCopy(bom, 0, final, 0, bom.Length);
System.Buffer.BlockCopy(bytes, 0, final, bom.Length, bytes.Length);
//Create are barcode using our new constructor
var q = new BarcodeQRCode(final, 100, 100, null);
//Add it to the document
doc.Add(q.GetImage());
謝謝,它工作。 – 2012-03-15 09:24:20
偉大的解決方案,它的工作原理! – dev 2015-01-07 15:19:18
看起來你可能不走運。我也試過,得到了和你一樣的結果。然後看了看Java API:。
「* CHARACTER_SET的值是字符串,可以是CP437,SHIFT_JIS和 ISO-8859-1到ISO-8859-16默認值爲ISO-8859-1 * 「
最後,看了看iTextSharp的BarcodeQRCode
類的源代碼,以確認只有那些字符集支持。我絕不是Unicode或編碼方面的權威,但根據ISO/IEC 8859,上述字符集不適用於中文。
本質上同樣的伎倆,克里斯在他的回答做了可以通過條形碼提示指定UTF-8字符集來實現。
var hints = new Dictionary<EncodeHintType, Object>() {{EncodeHintType.CHARACTER_SET, "UTF-8"}};
var q = new BarcodeQRCode("\u6D4B", 100, 100, hints);
如果你想更安全,你可以用BOM字符'\uFEFF'
開始你的字符串,像克里斯建議,所以這將是"\uFEFF\u6D4B"
。
不幸的是,QR碼規範並不支持UTF-8,並且在這個主題上有很多討論,但事實是大多數QR碼閱讀器將正確讀取由此方法創建的代碼。
- 1. 生成QR條碼使用iTextSharp的
- 2. 如何在iPhone中生成QR碼?
- 3. 生成QR碼
- 4. 從生成的PNG旁邊的QR碼中添加文本
- 5. 自編碼QR條碼?
- 6. 在android中的QR碼生成器
- 7. 使用ItextSharp的文本條形碼
- 8. 如何判斷用什麼編碼生成亂碼的中文文本?
- 9. 生成阿拉伯文QR碼
- 10. 黑莓QR碼生成器.bar文件
- 11. QR條碼圖像與文本
- 12. 在QR碼中傳遞多個文本
- 13. 在PHP中生成動態QR碼
- 14. 使用Java在Android中生成QR碼
- 15. 如何使用PHP QR代碼庫生成300dpi QR碼?
- 16. Android的QR代碼生成
- 17. 以編程方式生成QR代碼
- 18. itextsharp中的頁腳文本和頁碼
- 19. 生成印地文語言文字的QR碼,印地文
- 20. zxing正在生成QR碼而不是條碼
- 21. iTextSharp在單個單元格中添加文本和條形碼?
- 22. 如何用Zxing 2.1庫生成QR碼?
- 23. 使用PHP QR碼生成器在PHP中創建QR碼與中心徽標
- 24. 如何在qt中生成條形碼?
- 25. 如何在php中生成條形碼
- 26. 在jasperReport中QR碼集成
- 27. 簡單的QR碼 - 在QR碼中合併文本/保存數字爲PNG
- 28. 如何生成我在C#中編碼爲Xml的文檔?
- 29. 需要幫助使用ZXing編碼文本到QR碼在Android
- 30. 如何使用zxing庫文件生成65 * 65 Qr代碼?
您可以嘗試使用[link](http://kuujinbo.info/cs/itext_cjk.aspx)中的不同字體並使用[this](http://sourceforge.net/project/shownotes.php?group_id = 72954&release_id = 368247)字體 – Vinay 2012-03-14 11:37:20
我不想繪製中文文本,我試圖在QR條形碼中編碼中文文本。 – iPDFdev 2012-03-14 12:13:22