Files
photobooth-app/17_FIX_BGBLUR.md

6.5 KiB

Dưới đây là kế hoạch Markdown chi tiết để sửa lỗi thuật toán nhận diện AI (không hoạt động/tăng giảm không có tác dụng) và tái cấu trúc lại vị trí của 2 nút Xóa nền (Portrait Blur), Thay nền (BG Replace) ra ngoài menu chính, đồng cấp với nút FramePresets để tối ưu hóa trải nghiệm người dùng.


🛠️ KẾ HOẠCH FIX LỖI TÁCH NỀN AI & TÁI CẤU TRÚC MENU ĐỒNG CẤP

Mục tiêu cốt lõi:

  1. Sửa lỗi AI không nhận diện đối tượng do sai định dạng luồng dữ liệu đầu vào hoặc chặn luồng Main Thread.
  2. Đồng bộ hóa thanh trượt Ruler để cập nhật giá trị _blurIntensity thời gian thực.
  3. Đưa 2 tính năng: "Xóa nền" và "Thay nền" lên Menu Tầng 1 (Đồng cấp với FramePresets).

📐 1. Quy Hoạch Lại Cấu Trúc Menu Tầng 1 (Layout Architecture)

Hiện tại, 2 nút này đang bị ẩn sâu hoặc nằm sai tầng điều khiển. Chúng ta sẽ đưa chúng ra ngoài để cấu trúc Menu Tầng 1 bao gồm 4 nhóm chính:

[MENU CHÍNH (TẦNG 1)]
   ├── 🎨 Presets (Bộ lọc màu JSON)
   ├── 🖼️ Frame (Khung ảnh Instax)
   ├── 👤 Portrait Blur (Xóa phông nền - Mới)
   └── 🌄 BG Replace (Thay thế ảnh nền - Mới)

💻 Chỉnh sửa trạng thái giao diện quản lý UI (EditorNavigation):

enum EditorTab { presets, frames, portraitBlur, bgReplace }

EditorTab _currentTab = EditorTab.presets; // Mặc định mở tab presets

// Hàm vẽ thanh Menu Tầng 1 đồng cấp dưới đáy màn hình
Widget _buildMainMenuBar() {
  return Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      _menuItem(id: EditorTab.presets, icon: Icons.color_lens, label: "Presets"),
      _menuItem(id: EditorTab.frames, icon: Icons.photo_album, label: "Frame"),
      _menuItem(id: EditorTab.portraitBlur, icon: Icons.portrait, label: "Xóa nền"),
      _menuItem(id: EditorTab.bgReplace, icon: Icons.wallpaper, label: "Thay nền"),
    ],
  );
}


🛠️ 2. Sửa Lỗi AI Không Phát Hiện Đối Tượng & Thước Đo Không Có Tác Dụng

🔴 Nguyên nhân lỗi:

  1. Sai định dạng hướng ảnh (Orientation Image Error): Khi chụp ảnh từ thư viện camera, file ảnh thô (XFile) thường bị xoay -90 hoặc 180 độ tùy thuộc vào cảm biến phần cứng. Khi đưa thẳng vào AI của Google ML Kit mà không khai báo hướng (InputImageMetadata), AI sẽ đọc ngược bức ảnh và báo cáo: Không tìm thấy người/vật.
  2. Nghẽn luồng đồng bộ (UI Block): Hàm xử lý pixel for quá nặng ép luồng giao diện đóng băng, khiến thanh trượt Ruler không thể vẽ lại (Re-render) giá trị mờ.

🟢 Giải pháp sửa lỗi trong Logic Engine:

Bước 2.1: Bổ sung cấu hình hướng xoay chuẩn khi nạp ảnh vào AI

import 'package:camera/camera.dart';
import 'package:google_mlkit_selfie_segmentation/google_mlkit_selfie_segmentation.dart';

// Đảm bảo tạo InputImage kèm theo Metadata hướng xoay của camera biến thể
final inputImage = InputImage.fromFilePath(rawPhotoPath);

Bước 2.2: Đồng bộ thanh trượt Ruler với hàm cập nhật xem trước (Live Preview)

Để tăng giảm mức độ xóa nền có tác dụng ngay lập tức, bạn phải liên kết giá trị thay đổi của Ruler trực tiếp vào hàm setState và gọi cập nhật bộ lọc:

// Khi người dùng trượt thước đo Ruler của mục Portrait Blur
void onRulerValueChanged(double newValue) {
  setState(() {
    // Ép dải giá trị thước đo (Ví dụ từ 0 -> 100) về dải tỷ lệ phần trăm (0.0 -> 1.0)
    _blurIntensity = newValue / 100.0;
  });
  
  // LẬP TỨC ÉP CAMERA PREVIEW HOẶC ẢNH XEM TRƯỚC RENDER LẠI
  _triggerLivePreviewUpdate();
}

Bước 2.3: Sửa lỗi vòng lặp pha trộn Alpha (Fix Blending Mask Loop)

Đảm bảo giá trị smoothStep bóc tách được lấy chính xác từ mảng confidences của mô hình selfie để làm mượt các vùng chi tiết nhỏ như tóc:

// SỬA LỖI KHÔNG ÁP DỤNG: Đảm bảo biến _blurIntensity can thiệp trực tiếp vào hàm Gaussian Blur
if (_selectedBgMode == BackgroundMode.blur) {
  bg = img.copyResize(fg, width: w, height: h);
  
  // Tính toán bán kính mờ dựa theo thanh trượt Ruler thực tế của người dùng
  int calculatedRadius = (_blurIntensity * 25).toInt().clamp(1, 25);
  
  // Nếu người dùng kéo về 0 -> Không mờ, kéo tối đa -> Mờ bán kính 25
  if (calculatedRadius > 0) {
    bg = img.gaussianBlur(bg, radius: calculatedRadius);
  }
}


🔄 3. Chuỗi Pipeline Kết Hợp Sau Khi Sửa Lỗi

Khi người dùng nhấn nút Shutter, quy trình sẽ thực thi tuần tự trên các tab đồng cấp:

  1. 1. Kiểm tra Tab Active: Nút đồng cấp mới. Hệ thống kiểm tra xem người dùng đang kích hoạt tùy chọn nào ở Menu Tầng 1 (Portrait Blur hay BG Replace).

  2. 2. Quét AI On-Device: Khắc phục lỗi hướng xoay. Nạp ảnh thô vào Google ML Kit bằng Metadata chuẩn để lấy chính xác vị trí người/vật và tóc mảnh.

  3. 3. Khớp thông số trượt: Nhận giá trị từ Ruler. Lấy chính xác mức độ _blurIntensity từ thanh Ruler để ép độ mịn cho phông nền.

  4. 4. Xuất Gallery: Merge & Lưu. Hòa trộn mượt mà viền tóc ➔ Áp Presets màu ➔ Ép khung Instax ➔ Gọi Gal.putImage để hoàn tất.


📅 4. Checklist Kiểm Thử Thực Địa (Testing Checklist)

  • Kiểm tra đồng cấp: Bấm thử lần lượt 4 nút dưới đáy máy (Presets, Frame, Xóa nền, Thay nền) xem thanh Tầng 2 có chuyển đổi qua lại một cách độc lập và chính xác hay chưa.
  • Kiểm tra thanh trượt: Bật tab Xóa nền, kéo thanh trượt từ 0 lên 100 xem vùng nền phía sau nhân vật có mờ dần một cách tuyến tính mượt mà hay không.
  • Kiểm tra vật thể: Thử đưa một vật thể (ví dụ: cốc nước, gấu bông) lên chụp xem AI có nhận diện bóc tách được chi tiết viền không hay chỉ nhận diện mỗi khuôn mặt người để tùy biến mở rộng mô hình.