zp_cccd_scanner 1.2.0
zp_cccd_scanner: ^1.2.0 copied to clipboard
Flutter plugin quét và nhận diện thẻ CCCD / Căn cước Việt Nam (đủ 3 mẫu thẻ, 2 mặt) bằng camera native trên iOS (AVFoundation + Vision) và Android (CameraX + ML Kit).
zp_cccd_scanner #
Flutter plugin quét và nhận diện thẻ CCCD / Căn cước Việt Nam bằng camera native, hiệu ứng giống Zalo: khi phát hiện đúng thẻ trong khung, frame đóng băng và tia quét chạy từ trên xuống.
- iOS: AVFoundation + Vision (nhận diện chữ, QR, PDF417)
- Android: CameraX + ML Kit bundled (Text Recognition Latin, Barcode)
- Toàn bộ xử lý trên máy, không gửi ảnh ra ngoài
Thẻ được hỗ trợ #
| Mẫu thẻ | Mặt trước | Mặt sau |
|---|---|---|
| CCCD mã vạch (2016–2021) | ✅ | ✅ (PDF417) |
| CCCD gắn chip (2021–06/2024) | ✅ (QR) | ✅ (MRZ) |
| Thẻ Căn cước (từ 07/2024) | ✅ | ✅ (QR + MRZ) |
CMND (hết hiệu lực từ 01/01/2025), GPLX, hộ chiếu, thẻ ngân hàng, giấy chứng nhận căn cước... đều bị loại.
Chống nhận nhầm #
Chỉ chấp nhận khi có bằng chứng mạnh, rồi xác nhận lại lần 2 trên chính frame đã đóng băng:
- MRZ (mặt sau thẻ chip / Căn cước):
IDVNM, kiểm tra đủ 5 check digit ICAO 9303 (gồm check digit riêng của số định danh 12 số). - PDF417 trải ngang mép trên + cụm chữ đặc trưng (mặt sau CCCD mã vạch).
- Mặt trước: so khớp cả dòng tiêu đề, số định danh hợp lệ (mã tỉnh, thế kỷ, năm sinh) và khớp chéo với ngày sinh / giới tính in trên thẻ.
- Thẻ phải nằm trọn trong khung: dò 4 cạnh thẻ trên ảnh xám của vùng khung (dùng chung cho iOS/Android). Không chụp khi có góc bị cắt, thẻ quá gần / quá xa, hoặc tỉ lệ không đúng thẻ ID-1; lúc đó hiện hướng dẫn "Đưa toàn bộ thẻ vào trong khung".
- Cùng kết luận ở 2 frame liên tiếp trong 1.5 s.
Cài đặt #
dependencies:
zp_cccd_scanner: ^1.2.0
- iOS ≥ 15.5. Thêm vào
Info.plist:<key>NSCameraUsageDescription</key> <string>Cần dùng camera để quét thẻ CCCD</string> - Android minSdk 21, Activity phải là
FlutterActivity/FlutterFragmentActivity.
Sử dụng #
Mỗi CccdScannerView quét đúng một mặt. Luồng eKYC: chụp mặt trước rồi mặt sau, sau đó kiểm tra 2 mặt cùng một thẻ.
final front = await Navigator.push<CccdScanResult>(context, MaterialPageRoute(
builder: (context) => Scaffold(
body: CccdScannerView(
side: CccdSide.front,
onScanned: (r) async => Navigator.pop(context, r),
),
),
));
// ... quét mặt sau tương tự với side: CccdSide.back
switch (CccdPairing.check(front!, back!)) {
case CccdPairStatus.match:
case CccdPairStatus.sameTypeOnly:
// OK
break;
default:
// Hai mặt không cùng một thẻ
}
CccdScanResult gồm: type (mẫu thẻ), side, image (JPEG chứa trọn thẻ), corners (4 góc thẻ), cardRect, pairingKey (khóa nội bộ để ghép 2 mặt), highResolution (ảnh cắt từ ảnh chụp tĩnh độ phân giải cao hay từ frame video). Lib không trích xuất họ tên, ngày sinh...
Chất lượng ảnh #
- Chỉ chụp khi frame đủ nét: camera không đang lấy nét / đổi ống kính và độ nét không kém các frame vừa thấy thẻ.
- Mặc định (
highResolutionImage: true) ảnh thẻ được cắt từ ảnh chụp tĩnh (~12MP trên iOS, độ phân giải cao nhất trên Android); nếu máy không chụp được hoặc thẻ đã xê dịch thì dùng frame video. - iPhone có macro vẫn tự chuyển ống ultra-wide khi thẻ quá gần; lib zoom bù để khoảng cầm máy tự nhiên nằm ngoài vùng chuyển ống.
- Thiếu sáng: camera tự tăng bù sáng, không tự bật đèn (đèn dễ gây lóa mặt thẻ). Dùng
ZpCccdScanner.lowLightđể gợi ý vàZpCccdScanner.setTorch/ZpCccdScanner.torchcho nút đèn. - Gợi ý phụ
CccdScanTip(giữ yên máy, đưa ra xa, thiếu sáng) hiển thị trong dòng hướng dẫn mặc định; dùngonTipChangednếu tự làmhintBuilder.
Tùy biến giao diện: guideWidthFactor, guideAlignment, maskColor, idleColor, detectedColor, scanLineColor, scanDuration, hintBuilder, overlay. Bật showDebugOverlay để xem các dòng chữ / mã native đọc được, 4 cạnh thẻ dò được (khung cam) và lý do từ chối của frame gần nhất.
App demo #
cd example
fvm flutter run
Có 3 lựa chọn: quét riêng mặt trước, quét riêng mặt sau, và luồng eKYC (trước → sau → kiểm tra cùng thẻ).