最近开发中遇到了一个需求,就是实现一个类似于微信中
打开图片(预览), 针对有二维码
的图片,展示识别图中二维码
的选项, 对于没有二维码的图片,不展示.
一开始接到这样的需求,我 直接去pub.dev/ 市场里面搜 有关二维码扫描的 库, 但大多库都是 打开相机然后调取摄像头 进行扫描的, 不太满足我的场景. 我希望能够 直接从 图片的在线链接
或者 图片文件信息
读取图中的二维码.
一开始我找到了qrcode , github.com/wu9007/qrco…, 这个库支持从相册选择图片, 或者从图片的路径 进行读取二维码数据. 这是官方下的使用
import 'package:qrscan/qrscan.dart' as scanner;
// Select Bar-Code or QR-Code photos for analysis
String photoScanResult = await scanner.scanPhoto();
// Generating QR-Code
Uint8List result = await scanner.generateBarCode('https://github.com/leyan95/qrcode_scanner');
// Scanning the image of the specified path
String barcode = await scanner.scanPath(path);
// Parse to code string with uint8list
File file = await ImagePicker.pickImage(source: ImageSource.camera);
Uint8List bytes = file.readAsBytesSync();
String barcode = await scanner.scanBytes(uint8list);
但是无奈的是,这个库发布较早, 包规范不符合目前的标准,导致无法安装下来, 索性就放弃了.
再后来找到了mobile_scanner
, 我把该库的例子下载到本地, 试跑了一下, 功能很强大, 也包含上方我的需求, 提供路径,然后获取该文件中的二维码. 但是奈何 体积较大
, 老板不让用. 无奈之下,我只好继续找了.
再后来,我在pub get 市场找到了这个小众. 该库的特征正好迎合了我的需求.
- ✅ 从相机扫描(支持 Android、IOS、Web
- ✅ 从图像文件扫描
体积小, 且使用简单.
从相机扫描
ScanView(
onResult: (List<Result> results),
),
从图像文件扫描
List<Result> results = await scanImage(await file.readAsBytes());
// 扫描网络图片中的二维码
Future<void> scanQRCodeFromUrl(String imageUrl) async {
final Uint8List bytes = await getCachedImageBytes(imageUrl);
final List<Result>? results = await scanImage(bytes,maxSize: 800);
if (results != null && results.isNotEmpty) {
_scannedData = results.first.text;
if (_scannedData!.isNotEmpty) {
NavigatorUtil.openUrl(_scannedData!);
Navigator.pop(context);
} else {
setState(() {
_scannedData = '扫描到的文本不是有效的 URL: $_scannedData';
});
}
}else{
ToastUtils.showToast("无内容");
}
}
解析:
- 传入图片 url
- 根据url 获取缓存中的图片的 字节
- 通过
scanImage
方法 根据图片的字节 获取图片的中二维码 - 有数据(读取二维码的内容), 进行跳转
- 无数据进行提示
下面我再说一下吧, 因为我们的app的图片都是缓存本地的. 然后如何根据图片的url 获取对应缓存的本地地址吧
.
cached_network_image 提供了根据图片url 获取图片文件的.
var file = await CachedNetworkImageProvider.defaultCacheManager.getSingleFile(imageUrl);
对于getSingleFile 方法的介绍
abstract class BaseCacheManager {
/// Get the file from the cache and/or online, depending on availability and age.
/// Downloaded form [url], [headers] can be used for example for authentication.
/// When a file is cached it is return directly, when it is too old the file is
/// downloaded in the background. When a cached file is not available the
/// newly downloaded file is returned.
/// 从缓存和/或在线获取文件,具体取决于可用性和期限。
/// 下载的表单 [url]、[headers] 可用于身份验证等。
/// 当文件被缓存时直接返回,当文件太旧时则返回
/// 在后台下载。当缓存文件不可用时
/// 返回新下载的文件。
Future<File> getSingleFile(
String url, {
String key,
Map<String, String> headers,
});
...
}
我们拿到该文件之后, 直接使用readAsBytes
获取文件的字节码即可.