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

能否结合camera与barcode_finder包实现文档拍照条码联动存储?

移动端条码文档拍摄与处理实现方案

核心需求

  • 调用相机拍摄带条码的文档照片
  • 从拍摄的照片中提取条码信息
  • 支持将照片+条码信息保存至本地内部存储,或上传至Dropbox

选定依赖包

  • camera: ^0.10.0+1:实现相机预览、拍照功能
  • barcode_finder: ^0.0.5:从照片中识别并提取条码数据

1. 相机初始化与拍照逻辑

先配置相机权限,再实现相机预览和拍照功能:

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';

List<CameraDescription>? cameras;

Future<void> initCamera() async {
  WidgetsFlutterBinding.ensureInitialized();
  cameras = await availableCameras();
}

class CameraScreen extends StatefulWidget {
  @override
  _CameraScreenState createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  late CameraController _controller;
  late Future<void> _initializeControllerFuture;

  @override
  void initState() {
    super.initState();
    _controller = CameraController(
      cameras![0], // 使用后置摄像头
      ResolutionPreset.medium,
    );
    _initializeControllerFuture = _controller.initialize();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<void>(
        future: _initializeControllerFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            return CameraPreview(_controller);
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          try {
            await _initializeControllerFuture;
            final image = await _controller.takePicture();
            // 跳转至条码识别处理页面
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => BarcodeProcessingScreen(imagePath: image.path),
              ),
            );
          } catch (e) {
            print(e);
          }
        },
        child: const Icon(Icons.camera_alt),
      ),
    );
  }
}

2. 条码信息提取

利用barcode_finder解析拍摄照片中的条码:

import 'package:barcode_finder/barcode_finder.dart';
import 'package:flutter/material.dart';
import 'dart:io';

class BarcodeProcessingScreen extends StatefulWidget {
  final String imagePath;
  const BarcodeProcessingScreen({Key? key, required this.imagePath}) : super(key: key);

  @override
  _BarcodeProcessingScreenState createState() => _BarcodeProcessingScreenState();
}

class _BarcodeProcessingScreenState extends State<BarcodeProcessingScreen> {
  String? _barcodeData;

  @override
  void initState() {
    super.initState();
    _extractBarcode();
  }

  Future<void> _extractBarcode() async {
    try {
      final result = await BarcodeFinder.scanImage(widget.imagePath);
      setState(() {
        _barcodeData = result;
      });
    } catch (e) {
      print('条码识别失败: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('条码处理')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('条码信息: ${_barcodeData ?? '识别中...'}'),
            const SizedBox(height: 20),
            Image.file(File(widget.imagePath)),
            const SizedBox(height: 20),
            Row(
              children: [
                ElevatedButton(
                  onPressed: _barcodeData != null ? _saveToLocal : null,
                  child: const Text('保存到本地'),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: _barcodeData != null ? _uploadToDropbox : null,
                  child: const Text('上传到Dropbox'),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }
}

3. 本地存储与Dropbox上传

本地存储实现

借助path_provider获取内部存储路径,保存照片和条码信息:

import 'dart:io';
import 'dart:convert';
import 'package:path_provider/path_provider.dart';

Future<void> _saveToLocal() async {
  final directory = await getApplicationDocumentsDirectory();
  // 复制照片到内部存储
  final savedImagePath = '${directory.path}/${DateTime.now().millisecondsSinceEpoch}.jpg';
  await File(widget.imagePath).copy(savedImagePath);
  // 保存条码信息为JSON文件
  final barcodeFile = File('${directory.path}/barcode_info_${DateTime.now().millisecondsSinceEpoch}.json');
  await barcodeFile.writeAsString(jsonEncode({
    'barcode': _barcodeData,
    'imagePath': savedImagePath,
    'timestamp': DateTime.now().toIso8601String(),
  }));
  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('保存成功')));
}

Dropbox上传实现

集成Dropbox API(可使用dropbox_client包)完成上传:

import 'package:dropbox_client/dropbox_client.dart';

Future<void> _uploadToDropbox() async {
  // 初始化Dropbox客户端(需替换为你的App Key)
  await Dropbox.init('YOUR_DROPBOX_APP_KEY');
  // 上传照片
  final imageFileName = 'documents/${DateTime.now().millisecondsSinceEpoch}.jpg';
  await Dropbox.upload(widget.imagePath, imageFileName, (uploaded, total) {
    // 可添加上传进度监听逻辑
  });
  // 上传条码信息文本文件
  final barcodeFileName = 'documents/barcode_info_${DateTime.now().millisecondsSinceEpoch}.txt';
  await Dropbox.uploadFromString(_barcodeData!, barcodeFileName);
  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('上传成功')));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 23:33:24