Describe the bug
Im trying out the example code provided in the firebase_ml_vision and when i scan the bar code it gives displayValue as
"{"typeNumber": "0", "errorCode": "3", "version": "65"}", rarely it gives the correct displayValue, for the same barcode it sometime gives correct output and sometimes with the above error code
I have attached the image for reference

Steps to reproduce the behavior:
...
const MaterialBarcodeScanner(
validRectangle: Rectangle(height: 400, width: 300),
),
...
App should show correct barcode value
Click To Expand
Doctor summary (to see all details, run flutter doctor -v):
[β] Flutter (Channel stable, 1.20.4, on Mac OS X 10.15.7 19H2, locale en-IN)
[β] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[β] Xcode - develop for iOS and macOS (Xcode 11.5)
[β] Android Studio (version 4.0)
[β] Connected device (1 available)
Click To Expand
Dart SDK 2.9.2
Flutter SDK 1.20.4
ml_vision 1.0.0+1
dependencies:
- camera 0.5.8+7 [flutter]
- cupertino_icons 0.1.3
- firebase_core 0.5.0 [firebase_core_platform_interface flutter quiver meta firebase_core_web]
- firebase_ml_vision 0.9.6+2 [flutter]
- flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine]
- image_picker 0.6.7+11 [flutter flutter_plugin_android_lifecycle image_picker_platform_interface]
- path_provider 1.6.18 [flutter path_provider_platform_interface path_provider_macos path_provider_linux path_provider_windows]
dev dependencies:
- flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel string_scanner term_glyph typed_data]
transitive dependencies:
- async 2.4.2 [collection]
- boolean_selector 2.0.0 [source_span string_scanner]
- characters 1.0.0
- charcode 1.1.3
- clock 1.0.1 [meta]
- collection 1.14.13
- fake_async 1.1.0 [clock collection]
- ffi 0.1.3
- file 5.2.1 [intl meta path]
- firebase 7.3.0 [http http_parser js]
- firebase_core_platform_interface 2.0.0 [flutter meta plugin_platform_interface quiver]
- firebase_core_web 0.2.0 [firebase firebase_core_platform_interface flutter flutter_web_plugins meta js]
- flutter_plugin_android_lifecycle 1.0.11 [flutter]
- flutter_web_plugins 0.0.0 [flutter characters collection meta typed_data vector_math]
- http 0.12.2 [http_parser path pedantic]
- http_parser 3.1.4 [charcode collection source_span string_scanner typed_data]
- image_picker_platform_interface 1.1.1 [flutter meta http plugin_platform_interface]
- intl 0.16.1 [path]
- js 0.6.2
- matcher 0.12.8 [stack_trace]
- meta 1.1.8
- path 1.7.0
- path_provider_linux 0.0.1+2 [path xdg_directories path_provider_platform_interface flutter]
- path_provider_macos 0.0.4+4 [flutter]
- path_provider_platform_interface 1.0.3 [flutter meta platform plugin_platform_interface]
- path_provider_windows 0.0.4+1 [path_provider_platform_interface meta path flutter ffi win32]
- pedantic 1.9.0
- platform 2.2.1
- plugin_platform_interface 1.0.2 [meta]
- process 3.0.13 [file intl meta path platform]
- quiver 2.1.3 [matcher meta]
- sky_engine 0.0.99
- source_span 1.7.0 [charcode collection meta path term_glyph]
- stack_trace 1.9.5 [path]
- stream_channel 2.0.0 [async]
- string_scanner 1.0.5 [charcode meta source_span]
- term_glyph 1.1.0
- test_api 0.2.17 [async boolean_selector collection meta path source_span stack_trace stream_channel string_scanner term_glyph matcher]
- typed_data 1.2.0 [collection]
- vector_math 2.0.8
- win32 1.7.3 [ffi]
- xdg_directories 0.1.0 [path process flutter]
code sample
// Copyright 2019 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 'dart:ui' show lerpDouble;
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'colors.dart';
import 'scanner_utils.dart';
enum AnimationState { search, barcodeNear, barcodeFound, endSearch }
class MaterialBarcodeScanner extends StatefulWidget {
const MaterialBarcodeScanner({
this.validRectangle = const Rectangle(width: 400, height: 300),
this.frameColor = kShrineScrim,
this.traceMultiplier = 1.2,
});
final Rectangle validRectangle;
final Color frameColor;
final double traceMultiplier;
@override
_MaterialBarcodeScannerState createState() => _MaterialBarcodeScannerState();
}
class _MaterialBarcodeScannerState extends State<MaterialBarcodeScanner>
with TickerProviderStateMixin {
CameraController _cameraController;
AnimationController _animationController;
String _scannerHint;
bool _closeWindow = false;
String _barcodePictureFilePath;
Size _previewSize;
AnimationState _currentState = AnimationState.search;
CustomPainter _animationPainter;
int _animationStart = DateTime.now().millisecondsSinceEpoch;
final BarcodeDetector _barcodeDetector =
FirebaseVision.instance.barcodeDetector();
@override
void initState() {
super.initState();
SystemChrome.setEnabledSystemUIOverlays(<SystemUiOverlay>[]);
SystemChrome.setPreferredOrientations(
<DeviceOrientation>[DeviceOrientation.portraitUp],
);
_initCameraAndScanner();
_switchAnimationState(AnimationState.search);
}
void _initCameraAndScanner() {
ScannerUtils.getCamera(CameraLensDirection.back).then(
(CameraDescription camera) async {
await _openCamera(camera);
await _startStreamingImagesToScanner(camera.sensorOrientation);
},
);
}
void _initAnimation(Duration duration) {
setState(() {
_animationPainter = null;
});
_animationController?.dispose();
_animationController = AnimationController(duration: duration, vsync: this);
}
void _switchAnimationState(AnimationState newState) {
if (newState == AnimationState.search) {
_initAnimation(const Duration(milliseconds: 750));
_animationPainter = RectangleOutlinePainter(
animation: RectangleTween(
Rectangle(
width: widget.validRectangle.width,
height: widget.validRectangle.height,
color: Colors.white,
),
Rectangle(
width: widget.validRectangle.width * widget.traceMultiplier,
height: widget.validRectangle.height * widget.traceMultiplier,
color: Colors.transparent,
),
).animate(_animationController),
);
_animationController.addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed) {
Future<void>.delayed(const Duration(milliseconds: 1600), () {
if (_currentState == AnimationState.search) {
_animationController.forward(from: 0);
}
});
}
});
} else if (newState == AnimationState.barcodeNear ||
newState == AnimationState.barcodeFound ||
newState == AnimationState.endSearch) {
double begin;
if (_currentState == AnimationState.barcodeNear) {
begin = lerpDouble(0.0, 0.5, _animationController.value);
} else if (_currentState == AnimationState.search) {
_initAnimation(const Duration(milliseconds: 500));
begin = 0.0;
}
_animationPainter = RectangleTracePainter(
rectangle: Rectangle(
width: widget.validRectangle.width,
height: widget.validRectangle.height,
color: newState == AnimationState.endSearch
? Colors.transparent
: Colors.white,
),
animation: Tween<double>(
begin: begin,
end: newState == AnimationState.barcodeNear ? 0.5 : 1.0,
).animate(_animationController),
);
if (newState == AnimationState.barcodeFound) {
_animationController.addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed) {
Future<void>.delayed(const Duration(milliseconds: 300), () {
if (_currentState != AnimationState.endSearch) {
_switchAnimationState(AnimationState.endSearch);
setState(() {});
_showBottomSheet();
}
});
}
});
}
}
_currentState = newState;
if (newState != AnimationState.endSearch) {
_animationController.forward(from: 0);
_animationStart = DateTime.now().millisecondsSinceEpoch;
}
}
Future<void> _openCamera(CameraDescription camera) async {
final ResolutionPreset preset =
defaultTargetPlatform == TargetPlatform.android
? ResolutionPreset.medium
: ResolutionPreset.low;
_cameraController = CameraController(camera, preset);
await _cameraController.initialize();
_previewSize = _cameraController.value.previewSize;
setState(() {});
}
Future<void> _startStreamingImagesToScanner(int sensorOrientation) async {
bool isDetecting = false;
final MediaQueryData data = MediaQuery.of(context);
_cameraController.startImageStream((CameraImage image) {
if (isDetecting) {
return;
}
isDetecting = true;
ScannerUtils.detect(
image: image,
detectInImage: _barcodeDetector.detectInImage,
imageRotation: sensorOrientation,
).then(
(dynamic result) {
_handleResult(
barcodes: result,
data: data,
imageSize: Size(image.width.toDouble(), image.height.toDouble()),
);
},
).whenComplete(() => isDetecting = false);
});
}
bool get _barcodeNearAnimationInProgress {
return _currentState == AnimationState.barcodeNear &&
DateTime.now().millisecondsSinceEpoch - _animationStart < 2500;
}
void _handleResult({
@required List<Barcode> barcodes,
@required MediaQueryData data,
@required Size imageSize,
}) {
if (!_cameraController.value.isStreamingImages) {
return;
}
final EdgeInsets padding = data.padding;
final double maxLogicalHeight =
data.size.height - padding.top - padding.bottom;
// Width & height are flipped from CameraController.previewSize on iOS
final double imageHeight = defaultTargetPlatform == TargetPlatform.iOS
? imageSize.height
: imageSize.width;
final double imageScale = imageHeight / maxLogicalHeight;
final double halfWidth = imageScale * widget.validRectangle.width / 2;
final double halfHeight = imageScale * widget.validRectangle.height / 2;
final Offset center = imageSize.center(Offset.zero);
final Rect validRect = Rect.fromLTRB(
center.dx - halfWidth,
center.dy - halfHeight,
center.dx + halfWidth,
center.dy + halfHeight,
);
for (Barcode barcode in barcodes) {
final Rect intersection = validRect.intersect(barcode.boundingBox);
final bool doesContain = intersection == barcode.boundingBox;
if (doesContain) {
_cameraController.stopImageStream().then((_) => _takePicture());
if (_currentState != AnimationState.barcodeFound) {
_closeWindow = true;
_scannerHint = 'Loading Information...';
_switchAnimationState(AnimationState.barcodeFound);
setState(() {});
}
return;
} else if (barcode.boundingBox.overlaps(validRect)) {
if (_currentState != AnimationState.barcodeNear) {
_scannerHint = 'Move closer to the barcode';
_switchAnimationState(AnimationState.barcodeNear);
setState(() {});
}
return;
}
}
if (_barcodeNearAnimationInProgress) {
return;
}
if (_currentState != AnimationState.search) {
_scannerHint = null;
_switchAnimationState(AnimationState.search);
setState(() {});
}
}
@override
void dispose() {
_currentState = AnimationState.endSearch;
_cameraController?.stopImageStream();
_cameraController?.dispose();
_animationController?.dispose();
_barcodeDetector.close();
SystemChrome.setPreferredOrientations(<DeviceOrientation>[]);
SystemChrome.setEnabledSystemUIOverlays(<SystemUiOverlay>[
SystemUiOverlay.top,
SystemUiOverlay.bottom,
]);
super.dispose();
}
Future<void> _takePicture() async {
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Pictures/barcodePics';
await Directory(dirPath).create(recursive: true);
final String timestamp = DateTime.now().millisecondsSinceEpoch.toString();
final String filePath = '$dirPath/$timestamp.jpg';
try {
await _cameraController.takePicture(filePath);
} on CameraException catch (e) {
print(e);
}
_cameraController.dispose();
_cameraController = null;
setState(() {
_barcodePictureFilePath = filePath;
});
}
Widget _buildCameraPreview() {
return Container(
color: Colors.black,
child: Transform.scale(
scale: _getImageZoom(MediaQuery.of(context)),
child: Center(
child: AspectRatio(
aspectRatio: _cameraController.value.aspectRatio,
child: CameraPreview(_cameraController),
),
),
),
);
}
double _getImageZoom(MediaQueryData data) {
final double logicalWidth = data.size.width;
final double logicalHeight = _previewSize.aspectRatio * logicalWidth;
final EdgeInsets padding = data.padding;
final double maxLogicalHeight =
data.size.height - padding.top - padding.bottom;
return maxLogicalHeight / logicalHeight;
}
void _showBottomSheet() {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
width: double.infinity,
height: 368,
child: Column(
children: <Widget>[
Container(
height: 56,
alignment: Alignment.centerLeft,
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.grey)),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(
'1 result found',
// TODO(bmparr): Switch body2 -> bodyText1 once https://github.com/flutter/flutter/pull/48547 makes it to stable.
// ignore: deprecated_member_use
style: Theme.of(context).textTheme.body2,
),
),
),
Expanded(
child: Container(
padding: const EdgeInsets.all(24),
child: Column(
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.asset(
'assets/span_book.jpg',
fit: BoxFit.cover,
width: 96,
height: 96,
),
Container(
height: 96,
margin: const EdgeInsets.only(left: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: const EdgeInsets.only(bottom: 4),
child: Text(
'SPAN Reader',
// TODO(bmparr): Switch body2 -> bodyText1 once https://github.com/flutter/flutter/pull/48547 makes it to stable.
// ignore: deprecated_member_use
style: Theme.of(context).textTheme.body2,
),
),
Text(
'Vol. 2',
// TODO(bmparr): Switch body2 -> bodyText1 once https://github.com/flutter/flutter/pull/48547 makes it to stable.
// ignore: deprecated_member_use
style: Theme.of(context).textTheme.body2,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Container(
margin:
const EdgeInsets.only(bottom: 3),
child: const Text('Material Design'),
),
const Text('120 pages'),
],
),
),
],
),
)
],
),
Container(
margin: const EdgeInsets.only(top: 30),
child: const Text(
'A Japanese & English accompaniment to the 2016 SPAN '
'conference.',
),
),
Expanded(
child: Container(
padding: const EdgeInsets.only(bottom: 4),
alignment: Alignment.bottomCenter,
child: ButtonTheme(
minWidth: 312,
height: 48,
child: RaisedButton.icon(
onPressed: () => Navigator.of(context).pop(),
color: kShrinePink100,
label: const Text('ADD TO CART - \$12.99'),
icon: const Icon(Icons.add_shopping_cart),
elevation: 8.0,
shape: const BeveledRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(7.0),
),
),
),
),
),
),
],
),
),
),
],
),
);
},
).then((_) => _reset());
}
void _reset() {
_initCameraAndScanner();
setState(() {
_closeWindow = false;
_barcodePictureFilePath = null;
_scannerHint = null;
_switchAnimationState(AnimationState.search);
});
}
@override
Widget build(BuildContext context) {
Widget background;
if (_barcodePictureFilePath != null) {
background = Container(
color: Colors.black,
child: Transform.scale(
scale: _getImageZoom(MediaQuery.of(context)),
child: Center(
child: Image.file(
File(_barcodePictureFilePath),
fit: BoxFit.fitWidth,
),
),
),
);
} else if (_cameraController != null &&
_cameraController.value.isInitialized) {
background = _buildCameraPreview();
} else {
background = Container(
color: Colors.black,
);
}
return SafeArea(
child: Scaffold(
body: Stack(
children: <Widget>[
background,
Container(
constraints: const BoxConstraints.expand(),
child: CustomPaint(
painter: WindowPainter(
windowSize: Size(widget.validRectangle.width,
widget.validRectangle.height),
outerFrameColor: widget.frameColor,
closeWindow: _closeWindow,
innerFrameColor: _currentState == AnimationState.endSearch
? Colors.transparent
: kShrineFrameBrown,
),
),
),
Positioned(
left: 0,
right: 0,
top: 0,
child: Container(
height: 56,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: const <Color>[Colors.black87, Colors.transparent],
),
),
),
),
Positioned(
left: 0.0,
bottom: 0.0,
right: 0.0,
height: 56,
child: Container(
color: kShrinePink50,
child: Center(
child: Text(
_scannerHint ?? 'Point your camera at a barcode',
style: Theme.of(context).textTheme.button,
),
),
),
),
Container(
constraints: const BoxConstraints.expand(),
child: CustomPaint(
painter: _animationPainter,
),
),
AppBar(
leading: IconButton(
icon: const Icon(Icons.close, color: Colors.white),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: Colors.transparent,
elevation: 0.0,
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.flash_off,
color: Colors.white,
),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.help_outline,
color: Colors.white,
),
onPressed: () {},
),
],
),
],
),
),
);
}
}
class WindowPainter extends CustomPainter {
WindowPainter({
@required this.windowSize,
this.outerFrameColor = Colors.white54,
this.innerFrameColor = const Color(0xFF442C2E),
this.innerFrameStrokeWidth = 3,
this.closeWindow = false,
});
final Size windowSize;
final Color outerFrameColor;
final Color innerFrameColor;
final double innerFrameStrokeWidth;
final bool closeWindow;
@override
void paint(Canvas canvas, Size size) {
final Offset center = size.center(Offset.zero);
final double windowHalfWidth = windowSize.width / 2;
final double windowHalfHeight = windowSize.height / 2;
final Rect windowRect = Rect.fromLTRB(
center.dx - windowHalfWidth,
center.dy - windowHalfHeight,
center.dx + windowHalfWidth,
center.dy + windowHalfHeight,
);
final Rect left =
Rect.fromLTRB(0, windowRect.top, windowRect.left, windowRect.bottom);
final Rect top = Rect.fromLTRB(0, 0, size.width, windowRect.top);
final Rect right = Rect.fromLTRB(
windowRect.right,
windowRect.top,
size.width,
windowRect.bottom,
);
final Rect bottom = Rect.fromLTRB(
0,
windowRect.bottom,
size.width,
size.height,
);
canvas.drawRect(
windowRect,
Paint()
..color = innerFrameColor
..style = PaintingStyle.stroke
..strokeWidth = innerFrameStrokeWidth);
final Paint paint = Paint()..color = outerFrameColor;
canvas.drawRect(left, paint);
canvas.drawRect(top, paint);
canvas.drawRect(right, paint);
canvas.drawRect(bottom, paint);
if (closeWindow) {
canvas.drawRect(windowRect, paint);
}
}
@override
bool shouldRepaint(WindowPainter oldDelegate) =>
oldDelegate.closeWindow != closeWindow;
}
class Rectangle {
const Rectangle({this.width, this.height, this.color});
final double width;
final double height;
final Color color;
static Rectangle lerp(Rectangle begin, Rectangle end, double t) {
Color color;
if (t > .5) {
color = Color.lerp(begin.color, end.color, (t - .5) / .25);
} else {
color = begin.color;
}
return Rectangle(
width: lerpDouble(begin.width, end.width, t),
height: lerpDouble(begin.height, end.height, t),
color: color,
);
}
}
class RectangleTween extends Tween<Rectangle> {
RectangleTween(Rectangle begin, Rectangle end)
: super(begin: begin, end: end);
@override
Rectangle lerp(double t) => Rectangle.lerp(begin, end, t);
}
class RectangleOutlinePainter extends CustomPainter {
RectangleOutlinePainter({
@required this.animation,
this.strokeWidth = 3,
}) : super(repaint: animation);
final Animation<Rectangle> animation;
final double strokeWidth;
@override
void paint(Canvas canvas, Size size) {
final Rectangle rectangle = animation.value;
final Paint paint = Paint()
..strokeWidth = strokeWidth
..color = rectangle.color
..style = PaintingStyle.stroke;
final Offset center = size.center(Offset.zero);
final double halfWidth = rectangle.width / 2;
final double halfHeight = rectangle.height / 2;
final Rect rect = Rect.fromLTRB(
center.dx - halfWidth,
center.dy - halfHeight,
center.dx + halfWidth,
center.dy + halfHeight,
);
canvas.drawRect(rect, paint);
}
@override
bool shouldRepaint(RectangleOutlinePainter oldDelegate) => false;
}
class RectangleTracePainter extends CustomPainter {
RectangleTracePainter({
@required this.animation,
@required this.rectangle,
this.strokeWidth = 3,
}) : super(repaint: animation);
final Animation<double> animation;
final Rectangle rectangle;
final double strokeWidth;
@override
void paint(Canvas canvas, Size size) {
final double value = animation.value;
final Offset center = size.center(Offset.zero);
final double halfWidth = rectangle.width / 2;
final double halfHeight = rectangle.height / 2;
final Rect rect = Rect.fromLTRB(
center.dx - halfWidth,
center.dy - halfHeight,
center.dx + halfWidth,
center.dy + halfHeight,
);
final Paint paint = Paint()
..strokeWidth = strokeWidth
..color = rectangle.color;
final double halfStrokeWidth = strokeWidth / 2;
final double heightProportion = (halfStrokeWidth + rect.height) * value;
final double widthProportion = (halfStrokeWidth + rect.width) * value;
canvas.drawLine(
Offset(rect.right, rect.bottom + halfStrokeWidth),
Offset(rect.right, rect.bottom - heightProportion),
paint,
);
canvas.drawLine(
Offset(rect.right + halfStrokeWidth, rect.bottom),
Offset(rect.right - widthProportion, rect.bottom),
paint,
);
canvas.drawLine(
Offset(rect.left, rect.top - halfStrokeWidth),
Offset(rect.left, rect.top + heightProportion),
paint,
);
canvas.drawLine(
Offset(rect.left - halfStrokeWidth, rect.top),
Offset(rect.left + widthProportion, rect.top),
paint,
);
}
@override
bool shouldRepaint(RectangleTracePainter oldDelegate) => false;
}
flutter doctor -v
[β] Flutter (Channel stable, 1.22.0, on Mac OS X 10.15.7 19H2, locale en-GB)
β’ Flutter version 1.22.0 at /Users/tahatesser/Code/flutter_stable
β’ Framework revision d408d302e2 (3 days ago), 2020-09-29 11:49:17 -0700
β’ Engine revision 5babba6c4d
β’ Dart version 2.10.0
[β] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
β’ Android SDK at /Users/tahatesser/Code/sdk
β’ Platform android-30, build-tools 30.0.2
β’ ANDROID_HOME = /Users/tahatesser/Code/sdk
β’ Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
β’ Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
β’ All Android licenses accepted.
[β] Xcode - develop for iOS and macOS (Xcode 12.0.1)
β’ Xcode at /Applications/Xcode.app/Contents/Developer
β’ Xcode 12.0.1, Build version 12A7300
β’ CocoaPods version 1.9.3
[β] Android Studio (version 4.0)
β’ Android Studio at /Applications/Android Studio.app/Contents
β’ Flutter plugin version 50.0.1
β’ Dart plugin version 193.7547
β’ Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
[β] VS Code (version 1.49.2)
β’ VS Code at /Applications/Visual Studio Code.app/Contents
β’ Flutter extension version 3.15.0
[β] Connected device (1 available)
β’ Tahaβs iPhone (mobile) β’ 00008020-001059882212002E β’ ios β’ iOS 14.0.1
β’ No issues found!
Set the ResolutionPreset.medium to ResolutionPreset.high will solve the issue