- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在使用 Flutter 框架开发移动应用程序。
我需要读取二维码,我已经成功实现了Barcode Scan库,基于 ZXing至decode一个通过相机。
现在我还想增加一个机会,可以从图库中挑选包含 QR 码的图像并进行解码,而无需通过相机。
我检查了我正在使用的库以及这个库,但没有找到任何对此类功能的引用:qrcode_reader , qr .但徒劳无功。
暗示使用纯 Dart 逐字节序列化和解码图像的解决方案也是可以接受的。
最佳答案
正如我在评论中建议的那样,您可以尝试使用 firebase_ml_vision
包。
永远记住:
You must also configure Firebase for each platform project: Android and iOS (see the example folder or https://codelabs.developers.google.com/codelabs/flutter-firebase/#4 for step by step details).
在这个例子中(取自官方的,但有一个特定的插件版本——不是最新的)我们使用image_picker
插件从设备获取图像,然后我们解码二维码。
pubspec.yaml
firebase_ml_vision: 0.2.1
image_picker: 0.4.12+1
detector_painters.dart
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/material.dart';
enum Detector { barcode, face, label, cloudLabel, text }
class BarcodeDetectorPainter extends CustomPainter {
BarcodeDetectorPainter(this.absoluteImageSize, this.barcodeLocations);
final Size absoluteImageSize;
final List<Barcode> barcodeLocations;
@override
void paint(Canvas canvas, Size size) {
final double scaleX = size.width / absoluteImageSize.width;
final double scaleY = size.height / absoluteImageSize.height;
Rect scaleRect(Barcode barcode) {
return Rect.fromLTRB(
barcode.boundingBox.left * scaleX,
barcode.boundingBox.top * scaleY,
barcode.boundingBox.right * scaleX,
barcode.boundingBox.bottom * scaleY,
);
}
final Paint paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0;
for (Barcode barcode in barcodeLocations) {
paint.color = Colors.green;
canvas.drawRect(scaleRect(barcode), paint);
}
}
@override
bool shouldRepaint(BarcodeDetectorPainter oldDelegate) {
return oldDelegate.absoluteImageSize != absoluteImageSize ||
oldDelegate.barcodeLocations != barcodeLocations;
}
}
class FaceDetectorPainter extends CustomPainter {
FaceDetectorPainter(this.absoluteImageSize, this.faces);
final Size absoluteImageSize;
final List<Face> faces;
@override
void paint(Canvas canvas, Size size) {
final double scaleX = size.width / absoluteImageSize.width;
final double scaleY = size.height / absoluteImageSize.height;
final Paint paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = Colors.red;
for (Face face in faces) {
canvas.drawRect(
Rect.fromLTRB(
face.boundingBox.left * scaleX,
face.boundingBox.top * scaleY,
face.boundingBox.right * scaleX,
face.boundingBox.bottom * scaleY,
),
paint,
);
}
}
@override
bool shouldRepaint(FaceDetectorPainter oldDelegate) {
return oldDelegate.absoluteImageSize != absoluteImageSize ||
oldDelegate.faces != faces;
}
}
class LabelDetectorPainter extends CustomPainter {
LabelDetectorPainter(this.absoluteImageSize, this.labels);
final Size absoluteImageSize;
final List<Label> labels;
@override
void paint(Canvas canvas, Size size) {
final ui.ParagraphBuilder builder = ui.ParagraphBuilder(
ui.ParagraphStyle(
textAlign: TextAlign.left,
fontSize: 23.0,
textDirection: TextDirection.ltr),
);
builder.pushStyle(ui.TextStyle(color: Colors.green));
for (Label label in labels) {
builder.addText('Label: ${label.label}, '
'Confidence: ${label.confidence.toStringAsFixed(2)}\n');
}
builder.pop();
canvas.drawParagraph(
builder.build()
..layout(ui.ParagraphConstraints(
width: size.width,
)),
const Offset(0.0, 0.0),
);
}
@override
bool shouldRepaint(LabelDetectorPainter oldDelegate) {
return oldDelegate.absoluteImageSize != absoluteImageSize ||
oldDelegate.labels != labels;
}
}
// Paints rectangles around all the text in the image.
class TextDetectorPainter extends CustomPainter {
TextDetectorPainter(this.absoluteImageSize, this.visionText);
final Size absoluteImageSize;
final VisionText visionText;
@override
void paint(Canvas canvas, Size size) {
final double scaleX = size.width / absoluteImageSize.width;
final double scaleY = size.height / absoluteImageSize.height;
Rect scaleRect(TextContainer container) {
return Rect.fromLTRB(
container.boundingBox.left * scaleX,
container.boundingBox.top * scaleY,
container.boundingBox.right * scaleX,
container.boundingBox.bottom * scaleY,
);
}
final Paint paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0;
for (TextBlock block in visionText.blocks) {
for (TextLine line in block.lines) {
for (TextElement element in line.elements) {
paint.color = Colors.green;
canvas.drawRect(scaleRect(element), paint);
}
paint.color = Colors.yellow;
canvas.drawRect(scaleRect(line), paint);
}
paint.color = Colors.red;
canvas.drawRect(scaleRect(block), paint);
}
}
@override
bool shouldRepaint(TextDetectorPainter oldDelegate) {
return oldDelegate.absoluteImageSize != absoluteImageSize ||
oldDelegate.visionText != visionText;
}
}
main.dart
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'detector_painters.dart';
void main() => runApp(MaterialApp(home: _MyHomePage()));
class _MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<_MyHomePage> {
File _imageFile;
Size _imageSize;
dynamic _scanResults;
String _title = 'ML Vision Example';
Detector _currentDetector = Detector.text;
Future<void> _getAndScanImage() async {
setState(() {
_imageFile = null;
_imageSize = null;
});
final File imageFile =
await ImagePicker.pickImage(source: ImageSource.gallery);
if (imageFile != null) {
_getImageSize(imageFile);
_scanImage(imageFile);
}
setState(() {
_imageFile = imageFile;
});
}
Future<void> _getImageSize(File imageFile) async {
final Completer<Size> completer = Completer<Size>();
final Image image = Image.file(imageFile);
image.image.resolve(const ImageConfiguration()).addListener(
(ImageInfo info, bool _) {
completer.complete(Size(
info.image.width.toDouble(),
info.image.height.toDouble(),
));
},
);
final Size imageSize = await completer.future;
setState(() {
_imageSize = imageSize;
});
}
Future<void> _scanImage(File imageFile) async {
setState(() {
_scanResults = null;
});
final FirebaseVisionImage visionImage =
FirebaseVisionImage.fromFile(imageFile);
FirebaseVisionDetector detector;
switch (_currentDetector) {
case Detector.barcode:
detector = FirebaseVision.instance.barcodeDetector();
break;
case Detector.face:
detector = FirebaseVision.instance.faceDetector();
break;
case Detector.label:
detector = FirebaseVision.instance.labelDetector();
break;
case Detector.cloudLabel:
detector = FirebaseVision.instance.cloudLabelDetector();
break;
case Detector.text:
detector = FirebaseVision.instance.textRecognizer();
break;
default:
return;
}
final dynamic results =
await detector.detectInImage(visionImage) ?? <dynamic>[];
setState(() {
_scanResults = results;
if (results is List<Barcode>
&& results[0] is Barcode) {
Barcode res = results[0];
_title = res.displayValue;
}
});
}
CustomPaint _buildResults(Size imageSize, dynamic results) {
CustomPainter painter;
switch (_currentDetector) {
case Detector.barcode:
painter = BarcodeDetectorPainter(_imageSize, results);
break;
case Detector.face:
painter = FaceDetectorPainter(_imageSize, results);
break;
case Detector.label:
painter = LabelDetectorPainter(_imageSize, results);
break;
case Detector.cloudLabel:
painter = LabelDetectorPainter(_imageSize, results);
break;
case Detector.text:
painter = TextDetectorPainter(_imageSize, results);
break;
default:
break;
}
return CustomPaint(
painter: painter,
);
}
Widget _buildImage() {
return Container(
constraints: const BoxConstraints.expand(),
decoration: BoxDecoration(
image: DecorationImage(
image: Image.file(_imageFile).image,
fit: BoxFit.fill,
),
),
child: _imageSize == null || _scanResults == null
? const Center(
child: Text(
'Scanning...',
style: TextStyle(
color: Colors.green,
fontSize: 30.0,
),
),
)
: _buildResults(_imageSize, _scanResults),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_title),
actions: <Widget>[
PopupMenuButton<Detector>(
onSelected: (Detector result) {
_currentDetector = result;
if (_imageFile != null) _scanImage(_imageFile);
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<Detector>>[
const PopupMenuItem<Detector>(
child: Text('Detect Barcode'),
value: Detector.barcode,
),
const PopupMenuItem<Detector>(
child: Text('Detect Face'),
value: Detector.face,
),
const PopupMenuItem<Detector>(
child: Text('Detect Label'),
value: Detector.label,
),
const PopupMenuItem<Detector>(
child: Text('Detect Cloud Label'),
value: Detector.cloudLabel,
),
const PopupMenuItem<Detector>(
child: Text('Detect Text'),
value: Detector.text,
),
],
),
],
),
body: _imageFile == null
? const Center(child: Text('No image selected.'))
: _buildImage(),
floatingActionButton: FloatingActionButton(
onPressed: _getAndScanImage,
tooltip: 'Pick Image',
child: const Icon(Icons.add_a_photo),
),
);
}
}
iOS 和 Android 更新
为了在 iOS 上成功构建,我必须使用更低版本的 firebase_ml_vision
插件,否则你有这个 error .
pubspec.yaml
# https://github.com/firebase/firebase-ios-sdk/issues/2151
firebase_ml_vision: 0.1.2
image_picker: 0.4.12+1
我得到了你的错误,所以我也必须修改我的类(class)。
main.dart
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'detector_painters.dart';
void main() => runApp(MaterialApp(home: _MyHomePage()));
class _MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<_MyHomePage> {
File _imageFile;
Size _imageSize;
dynamic _scanResults;
String _title = 'ML Vision Example';
Detector _currentDetector = Detector.barcode;
Future<void> _getAndScanImage() async {
setState(() {
_imageFile = null;
_imageSize = null;
});
final File imageFile =
await ImagePicker.pickImage(source: ImageSource.gallery);
if (imageFile != null) {
_getImageSize(imageFile);
_scanImage(imageFile);
}
setState(() {
_imageFile = imageFile;
});
}
Future<void> _getImageSize(File imageFile) async {
final Completer<Size> completer = Completer<Size>();
final Image image = Image.file(imageFile);
image.image.resolve(const ImageConfiguration()).addListener(
(ImageInfo info, bool _) {
completer.complete(Size(
info.image.width.toDouble(),
info.image.height.toDouble(),
));
},
);
final Size imageSize = await completer.future;
setState(() {
_imageSize = imageSize;
});
}
Future<void> _scanImage(File imageFile) async {
setState(() {
_scanResults = null;
});
final FirebaseVisionImage visionImage =
FirebaseVisionImage.fromFile(imageFile);
FirebaseVisionDetector detector;
switch (_currentDetector) {
case Detector.barcode:
detector = FirebaseVision.instance.barcodeDetector();
break;
case Detector.face:
detector = FirebaseVision.instance.faceDetector();
break;
case Detector.label:
detector = FirebaseVision.instance.labelDetector();
break;
default:
return;
}
final dynamic results =
await detector.detectInImage(visionImage) ?? <dynamic>[];
setState(() {
_scanResults = results;
if (results is List<Barcode>
&& results[0] is Barcode) {
Barcode res = results[0];
_title = res.displayValue;
}
});
}
CustomPaint _buildResults(Size imageSize, dynamic results) {
CustomPainter painter;
switch (_currentDetector) {
case Detector.barcode:
painter = BarcodeDetectorPainter(_imageSize, results);
break;
case Detector.face:
painter = FaceDetectorPainter(_imageSize, results);
break;
case Detector.label:
painter = LabelDetectorPainter(_imageSize, results);
break;
case Detector.cloudLabel:
painter = LabelDetectorPainter(_imageSize, results);
break;
default:
break;
}
return CustomPaint(
painter: painter,
);
}
Widget _buildImage() {
return Container(
constraints: const BoxConstraints.expand(),
decoration: BoxDecoration(
image: DecorationImage(
image: Image.file(_imageFile).image,
fit: BoxFit.fill,
),
),
child: _imageSize == null || _scanResults == null
? const Center(
child: Text(
'Scanning...',
style: TextStyle(
color: Colors.green,
fontSize: 30.0,
),
),
)
: _buildResults(_imageSize, _scanResults),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_title),
actions: <Widget>[
PopupMenuButton<Detector>(
onSelected: (Detector result) {
_currentDetector = result;
if (_imageFile != null) _scanImage(_imageFile);
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<Detector>>[
const PopupMenuItem<Detector>(
child: Text('Detect Barcode'),
value: Detector.barcode,
),
const PopupMenuItem<Detector>(
child: Text('Detect Face'),
value: Detector.face,
),
const PopupMenuItem<Detector>(
child: Text('Detect Label'),
value: Detector.label,
),
const PopupMenuItem<Detector>(
child: Text('Detect Cloud Label'),
value: Detector.cloudLabel,
),
const PopupMenuItem<Detector>(
child: Text('Detect Text'),
value: Detector.text,
),
],
),
],
),
body: _imageFile == null
? const Center(child: Text('No image selected.'))
: _buildImage(),
floatingActionButton: FloatingActionButton(
onPressed: _getAndScanImage,
tooltip: 'Pick Image',
child: const Icon(Icons.add_a_photo),
),
);
}
}
detector_painters.dart
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/material.dart';
enum Detector { barcode, face, label, cloudLabel, text }
class BarcodeDetectorPainter extends CustomPainter {
BarcodeDetectorPainter(this.absoluteImageSize, this.barcodeLocations);
final Size absoluteImageSize;
final List<Barcode> barcodeLocations;
@override
void paint(Canvas canvas, Size size) {
final double scaleX = size.width / absoluteImageSize.width;
final double scaleY = size.height / absoluteImageSize.height;
Rect scaleRect(Barcode barcode) {
return Rect.fromLTRB(
barcode.boundingBox.left * scaleX,
barcode.boundingBox.top * scaleY,
barcode.boundingBox.right * scaleX,
barcode.boundingBox.bottom * scaleY,
);
}
final Paint paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0;
for (Barcode barcode in barcodeLocations) {
paint.color = Colors.green;
canvas.drawRect(scaleRect(barcode), paint);
}
}
@override
bool shouldRepaint(BarcodeDetectorPainter oldDelegate) {
return oldDelegate.absoluteImageSize != absoluteImageSize ||
oldDelegate.barcodeLocations != barcodeLocations;
}
}
class FaceDetectorPainter extends CustomPainter {
FaceDetectorPainter(this.absoluteImageSize, this.faces);
final Size absoluteImageSize;
final List<Face> faces;
@override
void paint(Canvas canvas, Size size) {
final double scaleX = size.width / absoluteImageSize.width;
final double scaleY = size.height / absoluteImageSize.height;
final Paint paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = Colors.red;
for (Face face in faces) {
canvas.drawRect(
Rect.fromLTRB(
face.boundingBox.left * scaleX,
face.boundingBox.top * scaleY,
face.boundingBox.right * scaleX,
face.boundingBox.bottom * scaleY,
),
paint,
);
}
}
@override
bool shouldRepaint(FaceDetectorPainter oldDelegate) {
return oldDelegate.absoluteImageSize != absoluteImageSize ||
oldDelegate.faces != faces;
}
}
class LabelDetectorPainter extends CustomPainter {
LabelDetectorPainter(this.absoluteImageSize, this.labels);
final Size absoluteImageSize;
final List<Label> labels;
@override
void paint(Canvas canvas, Size size) {
final ui.ParagraphBuilder builder = ui.ParagraphBuilder(
ui.ParagraphStyle(
textAlign: TextAlign.left,
fontSize: 23.0,
textDirection: TextDirection.ltr),
);
builder.pushStyle(ui.TextStyle(color: Colors.green));
for (Label label in labels) {
builder.addText('Label: ${label.label}, '
'Confidence: ${label.confidence.toStringAsFixed(2)}\n');
}
builder.pop();
canvas.drawParagraph(
builder.build()
..layout(ui.ParagraphConstraints(
width: size.width,
)),
const Offset(0.0, 0.0),
);
}
@override
bool shouldRepaint(LabelDetectorPainter oldDelegate) {
return oldDelegate.absoluteImageSize != absoluteImageSize ||
oldDelegate.labels != labels;
}
}
关于dart - 在 Flutter 中从文件中读取二维码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50709800/
可以在 R 中生成二维码吗?是否有允许它的包? 最佳答案 现在在 CRAN 您可以使用 qrencoder包 - https://github.com/hrbrmstr/qrencoder - 这样做
我有一个使用相机扫描二维码的应用程序。当我打开应用程序并转到二维码阅读器时,一切正常。一旦我扫描代码,信息就会发送到另一个 Activity ,但是一旦我点击后退按钮,相机就会变黑(见下文),我就无法
有没有办法为一个二维码创建多个 Action ? 目标是扫描二维码并执行这些操作: 连接WIFI 转至特定网址 我可以用 2 个二维码完成这 2 个操作,但只有一个会更容易 最佳答案 你不能。 仅仅是
在我的应用程序中,我需要实现 Blackberry Messenger 中可用的功能,即用户可以通过扫描他们的 QR 码来添加其他用户。 我找到了可以帮助生成二维码的库,也找到了线程来帮助生成二维码。
我尝试了新的 Google Play 服务功能 - 条码/QR 扫描仪。在 sample应用程序通过点击按钮开始扫描,结果也会在点击时返回。 有没有办法改变它的行为以立即返回第一个检测到的条形码/二维
我正在寻找解密(不仅是解码)二维码的逻辑。最近我看到几个加密二维码的应用程序,比如QuickMark。 .例如,此 QR 使用密码“pass”解密为“StackOverflow”: 如果你使用一个没有
我的公司有一个通过 URL 访问的社交网络平台。 我们正在尝试找到一种方法在体育商店中宣传我们的 URL,只有您来到商店才能访问我们的网站 - 我们不希望将 URL 分享给任何地方的任何人。 我们考虑
我想根据字段卷号生成一个二维码,并使用 JavaScript 文件(客户端验证)将其显示在 ID 名为“vyas_qrcode”的 div 容器中。 生成二维码的逻辑在js文件(qrcode_js.j
我正在研究使用 Android、iOS 和可能的 Windows Phone 上的浏览器扫描二维码的可用方法。理想的解决方案是拥有一个既可以在移动设备屏幕上又可以在全尺寸计算机屏幕上运行的 Ang
我正在开发 Instagram、Snap Chat 和 Facebook 等社交应用。我需要生成用户配置文件的二维码。我从数据库中隐藏了用户 ID。我的应用程序中有一个扫描仪来扫描二维码。该功能运行良
我有一个用于生成 jpeg 和 png 格式的二维码的代码,但还想在 PHP 中生成带有背景图像的 svg 二维码。我正在使用 qrlib.php 生成 jpeg 和 png 格式。 最佳答案 QRl
我正在使用 primefaces 开发网络应用程序。我正在尝试在网页上显示条形码。除了 QR 码外,所有编码器都显示了。我读到这需要两个 jar 文件 barcode4j: 2.1 qrgen:1.4
我正在寻找一个库或方法来解码二维码(或可能是另一种形式的二维条码)并能够实际确定相机的位置和方向。这似乎应该是可行的,但我不完全确定。 有谁知道最好的路线是什么?或者,如果它甚至可能? 最佳答案 zx
我正在尝试创建一个 QR 码,如果在安装了 Facebook 应用程序的手机上扫描,Facebook 应用程序将直接转到 QR 码中保存的类似页面。我尝试过什么this website已经说过了,但没
我使用python-qrcode和reportlab,我想生成一个二维码并显示它而不是将它保存为图像。 def member_card(request): response = HttpRes
好的,我正在使用这个 Javascript QR 代码生成器:https://github.com/davidshimjs/qrcodejs 开箱即用,您可以通过将其包含在页面上来获得字符串输出。
我在检测二维码在哪里时遇到问题。 我需要在它周围画边框。 我使用 AVMetadataObject 贝塞尔曲线路径,但它不起作用。 请帮助我。 - (void)captureOutput:(AVCap
我正在使用已弃用的 Camera 类。我在 onPreviewFrame(byte[] data, Camera camera) 方法中进行处理。 Zbar 扫描仪没有触发“尝试反向”扫描的选项。我发
1、搭个界面 2、写代码 ? 1
我正在尝试使用 pyqrcode 库生成一个 vCard 二维码,但我不知道该怎么做。 我已经阅读了他们的文档 5 次,其中没有提到 vCard,只提到了 URL,在互联网上,我只能找到关于 wifi
我是一名优秀的程序员,十分优秀!