Skip to main content

zp_cccd_scanner 1.10.0 copy "zp_cccd_scanner: ^1.10.0" to clipboard
zp_cccd_scanner: ^1.10.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).

1.10.0 #

  • iOS: nới ràng buộc version onnxruntime-objc từ ~> 1.30.0 xuống >= 1.23.0 — sửa xung đột khi app host đã có sẵn 1 lib khác (vd flutter_onnxruntime) ghim đúng 1 bản onnxruntime-objc cụ thể khác 1.30.x: trước đây CocoaPods sẽ báo lỗi "không tìm được bản thoả mãn cả 2 ràng buộc" và app không build được. Đã xác nhận trực tiếp (so header, không chỉ đọc tài liệu) 4 API ObjC plugin này dùng (ORTEnv/ORTSession/ORTValue init, run(withInputs:outputNames:runOptions:), tensorData()) có chữ ký giống hệt ở bản 1.23.0, và đã build thật thành công khi ép CocoaPods resolve về đúng bản đó (giả lập đúng tình huống có lib khác ghim 1.23.0). Không đổi code Swift, không đổi hành vi — chỉ nới ràng buộc version để CocoaPods có thể gộp chung 1 bản ONNX Runtime cho cả app thay vì xung đột. App host không có dependency ONNX Runtime nào khác không bị ảnh hưởng (vẫn resolve về bản mới nhất như trước, đã kiểm chứng 1.30.0).

1.9.0 #

  • BREAKING: gỡ ZpCccdAiModel.int8 — chỉ còn ZpCccdAiModel.fp32. App nào đang dùng ZpCccdAiModel.int8 sẽ lỗi build khi lên phiên bản này, chuyển sang ZpCccdAiModel.fp32. File cccd_seg_int8.onnx (~3.2MB) không còn đóng gói trong asset Android/iOS. Lý do: đo thực tế cho thấy phần nặng nhất của plugin là thư viện native ONNX Runtime (~34-41MB tuỳ ABI), không phải file model (~10-14MB) — bỏ int8 chỉ tiết kiệm ~3.2MB trong khi đổi lại độ chính xác kém hơn rõ rệt (mAP50-95 box 0.945 so với 0.990 của fp32), không đáng đánh đổi. Model đã lượng tử hoá vẫn còn trong model_handover/ (tài liệu tham khảo, không đóng gói vào package) nếu cần.
  • Android: bỏ hẳn nhận diện khuôn mặt (com.google.mlkit:face-detection) — đo thực tế bằng cách build 2 app Flutter tối giản (có/không có plugin) rồi so sánh (xem .build/measure-size-impact.sh): tích hợp plugin vào app host giờ chỉ còn tăng +68.00MB trên arm64-v8a (trước đây +79.91MB sau khi gỡ int8, +81.69MB trước đó) — tiết kiệm thêm ~11.9MB. Tín hiệu này chỉ phục vụ chấm che avatar của luồng Hough cổ điển; khi bật AI, code đã chủ động không dùng tới (model AI tự có lớp "bị che" riêng). Hành vi đổi: luồng Hough cổ điển (không bật AI) giờ chỉ còn chấm che avatar bằng tín hiệu "độ phẳng" (quay lại đúng hành vi trước bản 1.6.0) — vật che có vân/texture riêng (vd ngón tay) có thể khó bị phát hiện hơn so với khi có thêm tín hiệu khuôn mặt. Không ảnh hưởng gì khi bật AI (ZpCccdScanner.aiModel != null) — AI chưa từng dùng tín hiệu này. iOS không đổi gì: nhận diện khuôn mặt trên iOS dùng Vision (framework hệ thống của Apple, không tốn thêm dung lượng IPA), nên giữ nguyên để không mất độ chính xác miễn phí. CccdObservation.faces/CccdStill.faces vẫn còn trên Dart (Android giờ luôn gửi null, được xử lý y hệt case "bộ dò lỗi/không chạy" đã có sẵn — không cần đổi gì ở tầng Dart).

1.8.0 #

  • Bỏ fallback về Hough khi đã chọn AI (thay đổi hành vi so với 1.7.0): trước đây nếu model AI nạp lỗi hoặc suy luận lỗi liên tục nhiều khung hình, thư viện tự động rơi về CardQuadDetector (Hough) cho phần còn lại của phiên. Từ bản này, đã set ZpCccdScanner.aiModel thì cả phiên chỉ dùng AI để dò 4 góc + bị che — không gọi Hough, không chấm che theo độ phẳng/khuôn mặt/màu của luồng cũ, và không tự chuyển sang Hough dù model nạp lỗi hay suy luận lỗi liên tục. Model không nạp được (ZpCccdScanner.aiActive == false) thì phiên đó không dò được thẻ — app host nên tự kiểm tra aiActive sau khi gọi start() để quyết định xử lý (báo lỗi người dùng, hoặc khởi tạo lại phiên với aiModel = null để dùng Hough).
  • Android: tách luồng nhận diện khỏi luồng vẽ camera: ML Kit (OCR/mã vạch) và suy luận AI nay chạy trên một ExecutorService riêng (detectExecutor), không còn dùng chung luồng với việc vẽ texture preview — một lượt nhận diện/suy luận chậm không còn làm giật hình xem trước. Thêm SessionOptions cho ONNX Runtime (intraOpNumThreads = 2, interOpNumThreads = 1, tắt spin) để nhường lõi CPU cho luồng vẽ. AiCardDetector.analyze() chuyển từ read lock sang write lock (livestream và ảnh tĩnh không còn suy luận chồng nhau).
  • Bỏ dò khuôn mặt + tín hiệu màu (chroma) khi đã chọn AI (Android lẫn iOS): 2 tín hiệu này chỉ phục vụ chấm che avatar/vân tay/QR/PDF417 của luồng Hough cũ — không cần khi AI đã đảm nhiệm dò che, bớt việc cho ML Kit Face Detection/Vision mỗi khung hình.
  • Sửa số liệu dung lượng tải về của mục "Dung lượng (thư viện native ONNX Runtime)" ở bản 1.7.0: bản libonnxruntime.so đo ở bản 1.7.0 là dung lượng cài đặt (không nén); đo thêm bằng gzip -9 trên cùng file cho dung lượng tải về thực tế qua Play Store: ~12.9MB (arm64-v8a), ~11.6MB (armeabi-v7a) — thấp hơn đáng kể so với ~24-41MB cài đặt đã công bố ở 1.7.0.
  • Màu 4 góc khung đổi khi khoá thẻ (thay đổi hành vi mặc định, áp dụng cho MỌI app, không cần bật cờ nào): từ lúc CccdScanState.verifying trở đi (gồm cả lúc rejected đang hold và done), màu 4 góc đổi thành CccdScannerView.lockedColor (mặc định Color(0xFF22C55E), xanh lá) thay vì tiếp tục dùng detectedColor như trước. detectedColor từ bản này không còn hiệu lực nhìn thấy được ở bất kỳ đâu (đã đánh dấu @Deprecated, giữ lại tham số chỉ để không phá API cũ) — app đã tuỳ biến detectedColor để chờ đổi màu lúc khoá thẻ cần chuyển sang tuỳ biến lockedColor thay thế.
  • trackCardCorners + freezeOnVerify (mặc định true): 4 góc khoá vào đúng thẻ thật lúc verifying: trong lúc đang tìm thẻ, 4 góc overlay LUÔN ở khung hướng dẫn tĩnh (kể cả khi bật trackCardCorners) — tránh cảm giác giật do quad dò được dao động nhẹ mỗi khung hình. Chỉ khi cả 2 cờ cùng bật VÀ thẻ đã khoá (verifying), 4 góc mới trượt mượt — đúng MỘT LẦN, bo tròn giống hệt 4 góc tĩnh — từ khung tĩnh tới đúng 4 góc thẻ thật đã dò được, và tia quét chạy dọc theo đúng hình thẻ đó (nghiêng theo thẻ nếu thẻ nghiêng) thay vì kẻ ngang cố định. Giữ nguyên vị trí này xuyên suốt rejected/done, không giật. trackCardCorners: false (mặc định) hoặc freezeOnVerify: false (chế độ lưới) không đổi gì so với trước.
  • Ẩn lớp phủ tối ngoài khung lúc đã khoá thẻ: từ lúc CccdScanState.verifying tới done, lớp phủ tối (maskColor) không còn vẽ nữa — ảnh đã đóng băng rõ ràng nên lớp phủ chỉ còn che bớt hình, không còn tác dụng hướng dẫn tìm thẻ. Hiện lại ngay khi bị từ chối (rejected) hoặc khi thực sự quét lại. Áp dụng cho MỌI app, không cần bật cờ nào; 4 góc/tia quét/lưới vẫn vẽ bình thường, chỉ lớp phủ tối bị ẩn.

1.7.0 #

  • Bộ dò thẻ bằng AI (tuỳ chọn, mặc định tắt): thêm ZpCccdAiModel (fp32/int8) và ZpCccdScanner.aiModel — set trước khi gọi ZpCccdScanner.start() để chọn dùng model AI (ONNX Runtime) dò 4 góc thẻ + phát hiện che khuất, thay cho bộ dò Hough transform cổ điển (CardQuadDetector) đã có từ 1.0.0. Mỗi phiên quét chỉ chạy đúng một trong hai kỹ thuật — không bao giờ cả hai cùng chạy trên một frame: bật AI thì Hough hoàn toàn không chạy trong phiên đó (kể cả ở bước xác thực ảnh tĩnh); không bật (hoặc native load model thất bại, xem aiActive bên dưới) thì dùng Hough như trước giờ.
    • AI chỉ dò hình học (4 góc thẻ + bị che hay không) — không đọc chữ, không phân loại thẻ, không thay thế CccdValidator (validator OCR/MRZ/QR không đổi gì, vẫn chạy như cũ dù bật AI hay không).
    • ZpCccdScanner.aiActive (read-only): true khi model yêu cầu đã load thành công trên máy hiện tại trong phiên này. Nếu native load model thất bại (thiếu asset, ABI thiết bị không hỗ trợ...), thư viện tự động rơi về bộ dò cổ điển cho cả phiên quét đó — không crash, không treo app.
    • Mặc định aiModel = null (AI tắt) — không đổi API, không đổi hành vi so với trước khi có tính năng này; app host hiện tại không cần sửa gì.
    • App demo: thêm 2 switch loại trừ lẫn nhau "Dùng AI dò thẻ (fp32)" / "Dùng AI dò thẻ (int8, nhẹ hơn)" để thử nhanh.
    • int8 nhẹ hơn, KHÔNG nhanh hơn: int8 nhỏ hơn fp32 (~3.2MB so với ~10.6MB) nhưng chạy chậm hơn ~36% trên CPU (đo trong model_handover/README.md mục 5: fp32 ~55ms/khung hình, int8 ~76ms, cùng một máy), và độ chính xác dò che khuất kém hơn một chút. Chọn int8 vì dung lượng, không phải vì tốc độ.
    • Giới hạn phạm vi dò che khuất của AI: model chỉ có lớp "bị che" riêng cho CCCD nhựa kiểu mới (cccd_moi_truoc_che/cccd_moi_sau_che, xem model_handover/README.md mục 2) — với CCCD nhựa kiểu cũ và CMT giấy, đường AI không có tín hiệu che khuất hình học nào (không giống bộ dò Hough cổ điển, vốn có kiểm tra che góc chung cho mọi hình dạng thẻ). Bật AI cho các loại thẻ này chỉ còn lại việc dò 4 góc, không dò được che khuất qua hình học.
  • Android minSdk nâng từ 21 lên 24 — bắt buộc bởi dependency mới com.microsoft.onnxruntime:onnxruntime-android:1.31.1. Ảnh hưởng mọi app host cập nhật lên bản này, kể cả app không bật AI (tương tự cách 1.6.0 đã thêm com.google.mlkit:face-detection — dependency đó không đổi gì ở bản này, chỉ nhắc lại để không nhầm với dependency ONNX Runtime mới này).
  • Dung lượng (file model): cả 2 file model AI (cccd_seg_fp32.onnx ~10.6MB, cccd_seg_int8.onnx ~3.2MB — tổng ~13.8MB) được đóng gói vô điều kiện vào asset của cả Android lẫn iOS, tăng dung lượng APK/IPA của mọi app host dù có bật AI hay không. Chưa hỗ trợ tách theo flavor/dynamic delivery ở bản này (known tradeoff, dự kiến cải thiện sau).
  • Dung lượng (thư viện native ONNX Runtime) — KHÁC, LỚN HƠN dung lượng file model ở trên: bản thân thư viện native onnxruntime-android/onnxruntime-c (không phải file .onnx) cũng tăng dung lượng đáng kể, đo trực tiếp trên bản dựng thật của release này:
    • Android: libonnxruntime.so nặng ~34.2MB (arm64-v8a, ABI phổ biến nhất trên máy thật), ~24.2MB (armeabi-v7a), ~40.7-40.8MB (x86/x86_64) — cộng thêm libonnxruntime4j_jni.so nhỏ (~60-120KB mỗi ABI). Một APK "fat" (không tách theo ABI) gộp cả 4 ABI; AAB/split APK (khuyến nghị) chỉ gửi đúng 1 ABI cho mỗi máy, nên thực tế người dùng cuối chỉ tải thêm ~24-41MB tuỳ ABI thiết bị, không phải tổng cả 4.
    • iOS: pod onnxruntime-c nặng ~243MB trên đĩa (du -sh thư mục pod — gồm nhiều lát kiến trúc: thiết bị thật + simulator arm64/x86_64 + macOS); riêng lát ios-arm64 (thiết bị thật) nặng ~46MB. Dung lượng thực tế cộng vào app sau khi linker loại bỏ phần không dùng (dead-code stripping/thinning) nhỏ hơn con số này nhưng KHÔNG được đo chính xác trong môi trường kiểm thử này (không có thiết bị thật + App Store Connect size report để đo).
  • Telemetry ONNX Runtime:
    • Android: đã xác nhận bị tắt từ bản này. ai.onnxruntime.TelemetryInitializer — một ContentProvider chạy ở mọi process khởi động app host (bất kể có bật AI hay không) nạp thư viện native ONNX Runtime và dựng hẳn một client telemetry Microsoft 1DS (endpoint https://mobile.events.data.microsoft.com/OneCollector/1.0 cứng trong code) — plugin gỡ provider này khỏi manifest (tools:node="remove") và tự gọi OrtEnvironment.setTelemetry(false) khi nạp model (phòng vệ kép). Đã kiểm chứng bằng build release thật: manifest merger log ghi rõ provider này bị REJECTED, và log runtime của chính ONNX Runtime xác nhận HttpClient telemetry "was not initialized". Tài liệu C API chính thức của ONNX Runtime ghi "Telemetry events are on by default since they are lightweight" — tức mặc định BẬT trên MỌI nền tảng, không phải chỉ Windows như bản mô tả trước đây của plugin này (đã sửa, xem bản phát hành trước).
    • Quyền INTERNET/ACCESS_NETWORK_STATE vẫn merge vào manifest app host dù provider đã bị gỡ (dependency vẫn tự khai 2 quyền này độc lập với provider). App host không muốn 2 quyền này có thể tự gỡ bằng tools:node="remove" trong chính manifest của mình — nhưng cân nhắc kỹ trước khi làm vậy nếu app còn dùng mạng cho việc khác (upload ảnh lên backend eKYC chẳng hạn).
    • iOS: đã triển khai tắt qua C API thô (OrtApi::DisableTelemetryEvents, vì onnxruntime-objc's ORTEnv không expose API này) — đã kiểm chứng chuỗi gọi CreateEnv→DisableTelemetryEvents chạy thành công, không crash, trên iOS Simulator. KHÔNG bắt được gói tin mạng thực tế để xác nhận 0% traffic (không có công cụ network-capture trong môi trường kiểm thử) — chỉ xác nhận lệnh gọi API công khai, tài liệu hoá của chính ONNX Runtime báo cáo thành công.
  • iOS: thêm dependency onnxruntime-objc (~> 1.30.0) qua CocoaPods; deployment target giữ nguyên 15.5 (đã cao hơn yêu cầu 15.1 của dependency nên không cần nâng). Podspec của plugin bật static_framework = true (bắt buộc vì onnxruntime-objc/onnxruntime-c mang theo thư viện tĩnh — chỉ áp dụng cho riêng pod của plugin, không ép linkage mode cho Podfile của app host).
  • Giấy phép AGPL-3.0: trọng số model AI bundle kèm (cccd_seg_fp32.onnx/ cccd_seg_int8.onnx) được train bắt đầu từ Ultralytics YOLO26 (giấy phép AGPL-3.0) nên phải xem là AGPL-3.0 (xem model_handover/README.md mục 7). Sản phẩm cần đóng source hoặc dùng thương mại theo cách không tương thích AGPL-3.0 thì cần tự kiểm tra điều khoản đúng phiên bản Ultralytics đã dùng (8.4.175) tại thời điểm phát hành, mua giấy phép Ultralytics Enterprise, hoặc train lại từ một model nền khác mà mình có giấy phép.
    • Dữ liệu huấn luyện ảnh che khuất: đây là ràng buộc khác, độc lập với AGPL-3.0 ở trên — ảnh che khuất tổng hợp dùng để train lấy ảnh thẻ gốc từ các bộ dữ liệu công khai (Roboflow) có điều khoản riêng (thường giới hạn phi thương mại), ảnh tổng hợp kế thừa điều khoản của ảnh gốc. Phải tự kiểm tra giấy phép của từng nguồn ảnh trước khi phát hành thương mại (xem model_handover/README.md mục 7).
  • Model AI nâng từ 8 lên 12 lớp: phân biệt riêng CCCD 2021 và thẻ Căn cước 2024 (trước đó gộp chung thành 1 lớp "CCCD nhựa kiểu mới") — xem model_handover/README.md mục 2. Id lớp 0-7 giữ nguyên ý nghĩa, chỉ đổi tên (cu→2016, cmt→cmnd, moi→2021); thêm lớp 8-11 cho CCCD 2024 (sạch/bị che, mặt trước/sau). Không đổi API, không đổi logic hình học (minAreaRectCorners).
    • Cảnh báo từ model_handover/README.md mục 5: bản 12 lớp kém hơn bản 8 lớp cũ ở phát hiện che nhỏ (1-8% diện tích ở góc — ví dụ che 1%: 84.0% so với 96.3% trước đó) và chặn nhầm thẻ sạch nhiều hơn (3.3% so với 1.5%). Bản int8 yếu hơn rõ rệt riêng cho thẻ 2024 (mAP50 cccd_2024_sau 0.962, recall cccd_2024_sau_che 0.933). Dữ liệu CCCD 2024 trong tập train rất ít (124 ảnh thật, phần lớn gần giống nhau; chỉ 5 ảnh che thật) — chưa có đánh giá trên thẻ 2024 chụp bằng camera thật.
  • CccdScannerView.trackCardCorners (mặc định false): khi bật, 4 góc overlay bám theo vị trí/góc nghiêng thật của thẻ đã dò được (Hough hoặc AI, dùng chung CardQuad.corners) thay vì đứng yên ở khung hướng dẫn — hiệu ứng "focus/khoá vào thẻ". Tắt theo mặc định nên không đổi hành vi app host hiện tại.

1.6.0 #

  • Dò che nội dung chính xác hơn (avatar, vân tay, QR, PDF417): bổ sung 2 tín hiệu mới chạy song song (OR) với kỹ thuật đo "độ phẳng" đã có từ trước, không thay thế:
    • Nhận diện khuôn mặt cho vùng avatar (Vision trên iOS, ML Kit Face Detection trên Android) — sửa đúng ca thực tế đã gặp: vật che có texture riêng (VD ngón tay) vẫn có thể "qua mặt" kỹ thuật đo độ phẳng một khi camera đã lấy nét tốt, trong khi dò khuôn mặt xác nhận trực tiếp có đúng khuôn mặt hay không nên không bị đánh lừa kiểu đó.
    • Dò màu cho vân tay/QR/PDF417 (các vùng in mực đen trắng) — vật che có màu (da tay, vải...) đọc khác hẳn mực in nên bắt được cả trường hợp texture đánh lừa độ phẳng.
    • Áp dụng cho cả frame preview lẫn ảnh tĩnh lúc chụp (backstop cuối cùng trước khi chấp nhận kết quả), cả 3 loại thẻ (CCCD mã vạch, CCCD gắn chip, Căn cước).
    • Không đổi API public — hành vi mặc định tương thích ngược hoàn toàn, app host không cần sửa gì để nhận lợi ích này.
  • Android: thêm dependency mới com.google.mlkit:face-detection — có thể tăng nhẹ dung lượng APK của app host (model nhận diện khuôn mặt đóng gói kèm).
  • Các ngưỡng mới (kMinFaceOverlapFraction, kMinColorValue, kMaxColoredFraction) là ước lượng ban đầu, sẽ tiếp tục hiệu chỉnh bằng log thiết bị thật ở các bản sau.

1.5.0 #

  • CccdScannerView.freezeOnVerify (mặc định true, giữ nguyên hành vi cũ): đặt false để không đóng băng khung hình khi xác thực lần 2 — camera tiếp tục chạy live (gọi retain() native thay vì freeze()), phủ hiệu ứng lưới (mesh) có dải sáng quét lặp lại (giống máy scan tài liệu) lên vùng thẻ trong lúc xác thực vẫn chạy ngầm trên frame đã giữ lại. Hint mặc định ở trạng thái verifying cũng đổi theo: "Giữ vững, đang chụp..." thay vì "Giữ yên điện thoại, đang chụp ảnh thẻ..." như khi freezeOnVerify: true.
  • CccdScannerView.tipWarningColor (mặc định null = không đổi màu): màu 4 góc khung khi đang tìm thẻ (CccdScanState.searching) mà có bất kỳ gợi ý CccdScanTip nào đang active (mất nét, đưa ra xa, thiếu sáng, sai loại giấy tờ, bị che — cả 5 tip) hoặc khi frame hiện tại chưa thấy giấy tờ nào.
  • CccdScannerView.onNoCandidateChanged: callback ValueChanged<bool> báo khi tín hiệu "frame hiện tại có/không thấy giấy tờ nào" đổi (chỉ có ý nghĩa lúc CccdScanState.searching). Dùng khi app host tự vẽ hint ở vị trí khác qua overlay thay vì hintBuilder mặc định.
  • Cả 3 đều tuỳ chọn, giữ giá trị mặc định như hành vi cũ — app host hiện tại không cần đổi gì.
  • Export mới cccdHintText/cccdTipText (src/hint_text.dart): 2 hàm thuần tuý sinh câu hint mặc định của thư viện, nay public để app host tự vẽ hint UI hoàn toàn riêng (VD đặt text ở vị trí khác ngoài vị trí mặc định) mà vẫn tái dùng đúng nguyên văn câu chữ của thư viện thay vì tự chép lại.
  • Cập nhật câu chữ hướng dẫn mặc định (chỉ ảnh hưởng app đang dùng hint mặc định; app có hintBuilder riêng không dùng text này nên không bị ảnh hưởng):
    • CccdScanTip.holdStill: "Giữ yên điện thoại để ảnh rõ nét" → "Giấy tờ tùy thân mất nét. Hãy giữ yên."
    • CccdScanTip.cardObscured: "Thẻ đang bị che khuất, vui lòng bỏ vật che (ngón tay...) ra khỏi thẻ" → "Giấy tờ tùy thân bị che một phần. Hãy tránh che bằng ngón tay hoặc các đồ vật khác."
    • CccdScanTip.otherDocument: "Đây không phải CCCD / Căn cước, vui lòng đưa đúng loại giấy tờ" → "Không khớp với loại giấy tờ tùy thân đã chọn. Hãy sử dụng đúng giấy tờ tùy thân hoặc chọn lại loại giấy tờ tùy thân của bạn."
    • Mới: khi đang tìm thẻ (searching) mà frame hiện tại không thấy giấy tờ nào (chưa có tip cụ thể), hiện "Không phát hiện thấy giấy tờ tùy thân. Hãy đặt giấy tờ tùy thân trong khung hình."

1.4.0 #

  • Chặn chụp khi góc thẻ bị che: khi ít nhất một góc thẻ có dấu hiệu bị che (ngón tay, vật cản...) — đặc biệt là che QR — thư viện không còn tự chụp/nhận diện thẻ đó nữa, kể cả khi phần chữ/QR còn lại vẫn đủ để đọc được. Báo qua onTipChanged với CccdScanTip.cardObscured mới để app hiển thị "Thẻ đang bị che khuất, vui lòng bỏ vật che ra khỏi thẻ". Nếu app có switch đầy đủ theo CccdScanTip thì cần thêm case cardObscured.
  • Chặn chụp khi vùng nội dung ở giữa thẻ bị che: mở rộng phát hiện che khuất ra ngoài 4 góc — chặn cả khi avatar, mã vạch (PDF417), QR, dòng MRZ, nhãn thông tin khác, hoặc vân tay bị che. Áp dụng cho cả 3 loại thẻ (CCCD mã vạch, CCCD gắn chip, Căn cước). Vẫn báo qua CccdScanTip.cardObscured đã có, không thêm tip/API mới.
  • Sửa lỗi: sau khi bỏ vật che ra, thư viện có thể vẫn báo "bị che" và chặn chụp rất lâu nếu vật che lướt qua rìa vùng theo dõi vài lần lúc rút ra (mỗi lần lại tính lại thời gian chờ 1.5s từ đầu). Giờ chỉ bằng chứng che kéo dài (đã làm mượt) mới giữ cooldown dài; 1 lần chạm thoáng qua chỉ giữ cooldown ngắn (0.5s), không cộng dồn.

1.3.0 #

  • Sửa lỗi: không nhận diện được mặt sau CCCD mã vạch cấp từ 2019 (VD thẻ cấp năm 2020). Từ 2019 cơ quan cấp đổi thành "Cục Cảnh sát quản lý hành chính về trật tự xã hội" — cùng tên với mặt sau thẻ chip — nên mặt sau bị nhận nhầm là thẻ chip và đòi MRZ. Giờ chỉ dùng dòng tiếng Anh làm dấu hiệu thẻ chip; mẫu mã vạch từ 2019 được nhận qua PDF417 hoặc đủ cụm chữ cơ quan cấp khi không có dòng MRZ.
  • onDiagnostic: sự kiện frame kèm chữ OCR và mã đọc được (có vị trí) để chạy lại nhận diện offline (test/replay/replay_log_test.dart).
  • CccdScanTip.otherDocument: báo qua onTipChanged khi khung hình rõ ràng là một loại giấy tờ khác (GPLX, hộ chiếu...), không phải CCCD/Căn cước. Nếu app có switch đầy đủ theo CccdScanTip thì cần thêm case otherDocument.
  • CccdScannerController, CccdManualCaptureResult: cho phép app host chụp ảnh thủ công vùng khung hướng dẫn khi auto-detect không nhận diện được sau một khoảng thời gian do app tự quyết định (ảnh gửi lên BE xử lý tiếp, không qua validator). CccdScannerView.controller (tuỳ chọn).

1.2.0 #

  • Lấy nét ổn định, không giật (đặc biệt iPhone Pro có macro):
    • iOS không còn ép AF quét lại mỗi khi khung hình thay đổi; chỉ dời điểm lấy nét khi lệch đủ xa hoặc khi chạm.
    • Android chỉ gửi lại tham số Camera2 khi vùng lấy nét / fps thực sự đổi.
    • Giữ macro (iOS tự chuyển ống ultra-wide khi thẻ quá gần), đồng thời zoom bù để khoảng cầm máy tự nhiên nằm ngoài vùng chuyển ống.
  • Không chụp ảnh mờ: native gửi kèm độ nét (phương sai Laplacian) và trạng thái đang lấy nét / vừa đổi ống kính; chỉ xác nhận frame đủ nét và đóng băng frame nét nhất.
  • Ảnh độ phân giải cao: chụp ảnh tĩnh (iOS AVCapturePhotoOutput ~12MP, Android ImageCapture độ phân giải cao nhất) ngay khi đóng băng, dò lại 4 góc thẻ trên ảnh đó rồi cắt; tự quay về frame video nếu không chụp được. CccdScanResult.highResolution cho biết nguồn ảnh.
  • Thiếu sáng: tự tăng bù sáng và cho phơi sáng lâu hơn (không tự bật đèn); gợi ý người dùng bật đèn.
  • Gợi ý phụ CccdScanTip (giữ yên máy, đưa ra xa, thiếu sáng) qua dòng hướng dẫn mặc định và onTipChanged.
  • API mới: ZpCccdScanner.torch, ZpCccdScanner.lowLight, CccdScannerView.highResolutionImage.
  • showDebugOverlay hiển thị thêm độ nét, ống kính đang dùng, zoom, khoảng cách ước lượng, độ sáng, ISO.
  • CccdScannerView.onDiagnostic: sự kiện chẩn đoán (thông số camera, từng frame, đóng băng, ảnh tĩnh, kết quả) để ghi log khi test; app example có mục xuất file log.
  • Sửa lỗi (có từ 1.0.0): mở liền 2 màn quét (VD mặt trước -> mặt sau) thì camera màn sau bị đen. Màn cũ dispose sau khi màn mới đã mở camera nên tắt nhầm camera mới và ngắt kênh event. Giờ ZpCccdScanner.stop(textureId) chỉ tắt đúng camera của mình, các listener dùng chung một luồng event, màn không còn ở trên cùng thì bỏ qua frame.
  • overlay của CccdScannerView nhận ràng buộc phủ kín view (ghi rõ trong tài liệu); app example đặt hàng nút lên trên cùng.

1.0.0 #

  • Phát hành đầu tiên trên pub.dev.
  • Nhận diện 3 mẫu thẻ còn hiệu lực, cả 2 mặt: CCCD mã vạch (2016), CCCD gắn chip (2021), thẻ Căn cước (2024).
  • Chống nhận nhầm: MRZ IDVNM đủ 5 check digit ICAO 9303, PDF417 + cụm chữ đặc trưng, tiêu đề + số định danh khớp chéo ngày sinh / giới tính; xác nhận lần 2 trên frame đã đóng băng.
  • Chỉ chụp khi thẻ nằm trọn trong khung (dò 4 cạnh thẻ); ảnh trả về chứa trọn thẻ kèm 4 góc.
  • Hiệu ứng giống Zalo: đóng băng frame và tia quét từ trên xuống khi phát hiện thẻ.
  • CccdScannerView quét từng mặt, báo khi đưa nhầm mặt / thẻ chưa nằm trọn trong khung; CccdPairing kiểm tra 2 mặt cùng một thẻ.
  • Camera native: iOS AVFoundation + Vision, Android CameraX + ML Kit (bundled); zoom, đèn flash, chạm để lấy nét.
0
likes
140
points
792
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

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).

Repository (GitHub)
View/report issues

Topics

#cccd #id-card #ekyc #scanner #camera

License

MIT (license)

Dependencies

flutter

More

Packages that depend on zp_cccd_scanner

Packages that implement zp_cccd_scanner