You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用qr_code_scanner包时,Flutter中如何截取扫码区域的截图

Fixing Black Screenshots with QR Code Scanner in Flutter

Hey there! I’ve run into this exact issue before—trying to capture a screenshot of the QR scanner view using RepaintBoundary just gives a black image, right? Let’s break down why this happens and how to fix it.

Why RepaintBoundary Isn’t Working

The QRView from the qr_code_scanner package renders the camera feed using native platform components (like Android’s SurfaceView or iOS’s AVCaptureSession). These components sit outside Flutter’s render tree, so RepaintBoundary can’t capture their content. Pausing the camera doesn’t help because the native view’s content still isn’t part of Flutter’s canvas.

Solution 1: Capture Camera Frames Directly via QRViewController

The QRViewController actually has a built-in method to grab the current camera frame, which bypasses the RepaintBoundary issue entirely. Here’s how to implement it:

Step 1: Add Required Dependencies

First, add these packages to your pubspec.yaml (for image processing and file handling):

dependencies:
  qr_code_scanner: ^1.0.1 # Use the latest version
  image: ^4.0.17
  path_provider: ^2.0.15

Step 2: Capture and Process the Frame

Use the captureImage() method from the controller to get the current camera frame, then convert and crop it to your needs:

import 'dart:typed_data';
import 'dart:io';
import 'package:image/image.dart' as img;
import 'package:path_provider/path_provider.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';

// Store your QRViewController instance
late QRViewController _controller;

Future<void> captureScannerScreenshot() async {
  try {
    // Capture the current camera frame
    final cameraImage = await _controller.captureImage();
    if (cameraImage == null) {
      print("Failed to capture frame");
      return;
    }

    // Convert the image to bytes
    final byteData = await cameraImage.toByteData(format: ImageByteFormat.png);
    if (byteData == null) return;
    final imageBytes = byteData.buffer.asUint8List();

    // Crop to the QR scanner region (adjust values based on your UI)
    final decodedImage = img.decodeImage(imageBytes);
    if (decodedImage != null) {
      // Example: Crop to a 60% width, 40% height region centered in the frame
      final cropX = (decodedImage.width * 0.2).toInt();
      final cropY = (decodedImage.height * 0.3).toInt();
      final cropWidth = (decodedImage.width * 0.6).toInt();
      final cropHeight = (decodedImage.height * 0.4).toInt();

      final croppedImage = img.copyCrop(
        decodedImage,
        x: cropX,
        y: cropY,
        width: cropWidth,
        height: cropHeight,
      );

      // Encode the cropped image to PNG
      final croppedBytes = img.encodePng(croppedImage);

      // Save to temporary directory (or use as needed)
      final tempDir = await getTemporaryDirectory();
      final screenshotFile = File('${tempDir.path}/qr_scanner_screenshot.png');
      await screenshotFile.writeAsBytes(croppedBytes);

      // Use the screenshot file (e.g., display it, share it)
      print("Screenshot saved to: ${screenshotFile.path}");
    }
  } catch (e) {
    print("Error capturing screenshot: $e");
  }
}

// Don't forget to initialize the controller in onQRViewCreated
void _onQRViewCreated(QRViewController controller) {
  _controller = controller;
  // Your existing QR scanning logic here
}

Step 3: Trigger the Screenshot

Call captureScannerScreenshot() when you need to grab the screenshot (e.g., on a button tap):

ElevatedButton(
  onPressed: captureScannerScreenshot,
  child: const Text("Capture QR Screenshot"),
)

Solution 2: Switch to a More Flexible Scanner Package (Alternative)

If you run into issues with qr_code_scanner’s captureImage() method, consider using the mobile_scanner package. It offers better control over camera frames and built-in screenshot support, while still handling QR scanning seamlessly.

Key Notes

  • You don’t need to pause the camera when using captureImage()—it grabs the current frame in real-time.
  • Adjust the crop values to match your actual QR scanner UI’s position and size.
  • Make sure you have the necessary camera permissions set up in your app (already required for qr_code_scanner).

This approach will give you a clear screenshot of just the scanner region, no black images included!

内容的提问来源于stack exchange,提问作者user24826

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 02:59:09