掃描生成的 vCard 二維碼,Android 手機顯示中文姓名亂碼。經對比發現:亂碼樣本的 ORG(組織)字段為空。補齊該字段固定值後,亂碼神奇消失。本文深度剖析根因,並匯總 PHP 生成二維碼四大主流方案與 Logo 嵌入技巧。
Android 掃碼庫在解析 vCard 時,會根據內容長度、字段完整度推測編碼。關鍵字段(如 ORG)缺失導致內容熵值過低,誤判為非 UTF-8 編碼,進而產生亂碼。補全必要字段即可修正編碼推測。
| 方案 | 特點 | 適用場景 |
|---|---|---|
| Google Chart API | 零依賴、URL 即生成、需外網 | 簡單展示、原型驗證 |
| PHP QR Code (phpqrcode) | 純 PHP、無擴展依賴、支援 Logo 嵌入 | 主流選擇、內網部署 |
| libqrencode (C 庫 + PHP 擴展) | 效能極佳、功能豐富、需編譯安裝 | 高併發、大量生成 |
| QRcode Perl CGI / PHP Scripts | 較老舊、參考價值大 | 學習研究 |
下載:phpqrcode
// 基礎生成
QRcode::png('code data text', 'filename.png'); // 存檔
QRcode::png('some text'); // 直接輸出圖片
phpqrcode.php 中 QRimage::png() 方法植入 Logopublic static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4, $saveandprint = FALSE, $mergePic = '') {
$image = self::image($frame, $pixelPerPoint, $outerFrame);
if ($mergePic) {
$im = imagecreatefrompng($mergePic);
$w = imagesx($im); $h = imagesy($im);
imagealphablending($image, true);
imagealphablending($im, true);
$qrw = (imagesx($image) - $w) / 2;
$qrh = (imagesy($image) - $h) / 2;
imagecopy($image, $im, $qrw, $qrh, 0, 0, $w, $h);
imagedestroy($im);
}
if ($filename === false) {
header("Content-type: image/png");
imagepng($image);
} else {
imagepng($image, $filename);
if ($saveandprint === TRUE) {
header("Content-type: image/png");
imagepng($image);
}
}
imagedestroy($image);
}
調用:QRcode::png('vCard 數據', 'qrcode.png', 4, 4, false, 'logo.png');
BEGIN:VCARD
VERSION:3.0
N:姓名
FN:顯示名稱
ORG:公司名稱(必填,防亂碼關鍵)
TEL;TYPE=CELL:手機
EMAIL:郵箱
ADR:地址
END:VCARD
確保 ORG、N、FN 等核心字段非空,配合 UTF-8 編碼輸出,徹底根治 Android 掃碼中文亂碼。