Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
mobile_scanner
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Elliot Shepherd
2022-08-14 12:35:34 +1000
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
f2b103eb2cb10065bef9ba60be32e1ef8597bdb6
f2b103eb
1 parent
b9abd6ee
optionally return image with barcode
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
250 additions
and
3 deletions
README.md
example/lib/barcode_scanner_returning_image.dart
example/lib/main.dart
ios/Classes/SwiftMobileScannerPlugin.swift
lib/src/mobile_scanner_controller.dart
lib/src/objects/barcode.dart
README.md
View file @
f2b103e
...
...
@@ -169,3 +169,41 @@ import 'package:mobile_scanner/mobile_scanner.dart';
}));
}
```
Example with controller and returning images
```
dart
import
'package:mobile_scanner/mobile_scanner.dart'
;
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'Mobile Scanner'
)),
body:
MobileScanner
(
controller:
MobileScannerController
(
facing:
CameraFacing
.
front
,
torchEnabled:
true
,
returnImage:
true
,
),
onDetect:
(
barcode
,
args
)
{
if
(
barcode
.
rawValue
==
null
)
{
debugPrint
(
'Failed to scan Barcode'
);
}
else
{
final
String
code
=
barcode
.
rawValue
!;
debugPrint
(
'Barcode found!
$code
'
);
debugPrint
(
'Image returned! length:
${barcode.image!.lengthInBytes}
b'
);
showDialog
(
context:
context
,
builder:
(
context
)
=>
Image
(
image:
MemoryImage
(
barcode
.
image
!)),
);
Future
.
delayed
(
const
Duration
(
seconds:
2
),
()
{
Navigator
.
pop
(
context
);
});
}
},
),
);
}
```
\ No newline at end of file
...
...
example/lib/barcode_scanner_returning_image.dart
0 → 100644
View file @
f2b103e
import
'dart:typed_data'
;
import
'package:flutter/material.dart'
;
import
'package:mobile_scanner/mobile_scanner.dart'
;
class
BarcodeScannerReturningImage
extends
StatefulWidget
{
const
BarcodeScannerReturningImage
({
Key
?
key
})
:
super
(
key:
key
);
@override
_BarcodeScannerReturningImageState
createState
()
=>
_BarcodeScannerReturningImageState
();
}
class
_BarcodeScannerReturningImageState
extends
State
<
BarcodeScannerReturningImage
>
with
SingleTickerProviderStateMixin
{
String
?
barcode
;
Uint8List
?
image
;
MobileScannerController
controller
=
MobileScannerController
(
torchEnabled:
true
,
returnImage:
true
,
// formats: [BarcodeFormat.qrCode]
// facing: CameraFacing.front,
);
bool
isStarted
=
true
;
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
backgroundColor:
Colors
.
black
,
body:
Builder
(
builder:
(
context
)
{
return
Stack
(
children:
[
MobileScanner
(
controller:
controller
,
fit:
BoxFit
.
contain
,
// allowDuplicates: true,
// controller: MobileScannerController(
// torchEnabled: true,
// facing: CameraFacing.front,
// ),
onDetect:
(
barcode
,
args
)
{
setState
(()
{
this
.
barcode
=
barcode
.
rawValue
;
showDialog
(
context:
context
,
builder:
(
context
)
=>
Image
(
image:
MemoryImage
(
image
!),
fit:
BoxFit
.
contain
,
),
);
image
=
barcode
.
image
;
});
},
),
Align
(
alignment:
Alignment
.
bottomCenter
,
child:
Container
(
alignment:
Alignment
.
bottomCenter
,
height:
100
,
color:
Colors
.
black
.
withOpacity
(
0.4
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
children:
[
IconButton
(
color:
Colors
.
white
,
icon:
ValueListenableBuilder
(
valueListenable:
controller
.
torchState
,
builder:
(
context
,
state
,
child
)
{
if
(
state
==
null
)
{
return
const
Icon
(
Icons
.
flash_off
,
color:
Colors
.
grey
,
);
}
switch
(
state
as
TorchState
)
{
case
TorchState
.
off
:
return
const
Icon
(
Icons
.
flash_off
,
color:
Colors
.
grey
,
);
case
TorchState
.
on
:
return
const
Icon
(
Icons
.
flash_on
,
color:
Colors
.
yellow
,
);
}
},
),
iconSize:
32.0
,
onPressed:
()
=>
controller
.
toggleTorch
(),
),
IconButton
(
color:
Colors
.
white
,
icon:
isStarted
?
const
Icon
(
Icons
.
stop
)
:
const
Icon
(
Icons
.
play_arrow
),
iconSize:
32.0
,
onPressed:
()
=>
setState
(()
{
isStarted
?
controller
.
stop
()
:
controller
.
start
();
isStarted
=
!
isStarted
;
}),
),
Center
(
child:
SizedBox
(
width:
MediaQuery
.
of
(
context
).
size
.
width
-
200
,
height:
50
,
child:
FittedBox
(
child:
Text
(
barcode
??
'Scan something!'
,
overflow:
TextOverflow
.
fade
,
style:
Theme
.
of
(
context
)
.
textTheme
.
headline4
!
.
copyWith
(
color:
Colors
.
white
),
),
),
),
),
IconButton
(
color:
Colors
.
white
,
icon:
ValueListenableBuilder
(
valueListenable:
controller
.
cameraFacingState
,
builder:
(
context
,
state
,
child
)
{
if
(
state
==
null
)
{
return
const
Icon
(
Icons
.
camera_front
);
}
switch
(
state
as
CameraFacing
)
{
case
CameraFacing
.
front
:
return
const
Icon
(
Icons
.
camera_front
);
case
CameraFacing
.
back
:
return
const
Icon
(
Icons
.
camera_rear
);
}
},
),
iconSize:
32.0
,
onPressed:
()
=>
controller
.
switchCamera
(),
),
SizedBox
(
width:
50
,
height:
50
,
child:
image
!=
null
?
Image
(
image:
MemoryImage
(
image
!),
fit:
BoxFit
.
contain
,
)
:
Container
(),
),
],
),
),
),
],
);
},
),
);
}
}
...
...
example/lib/main.dart
View file @
f2b103e
import
'package:flutter/material.dart'
;
import
'package:mobile_scanner_example/barcode_scanner_controller.dart'
;
import
'package:mobile_scanner_example/barcode_scanner_returning_image.dart'
;
import
'package:mobile_scanner_example/barcode_scanner_without_controller.dart'
;
void
main
(
)
=>
runApp
(
const
MaterialApp
(
home:
MyHome
()));
...
...
@@ -31,6 +32,17 @@ class MyHome extends StatelessWidget {
onPressed:
()
{
Navigator
.
of
(
context
).
push
(
MaterialPageRoute
(
builder:
(
context
)
=>
const
BarcodeScannerReturningImage
(),
),
);
},
child:
const
Text
(
'MobileScanner with Controller (returning image)'
),
),
ElevatedButton
(
onPressed:
()
{
Navigator
.
of
(
context
).
push
(
MaterialPageRoute
(
builder:
(
context
)
=>
const
BarcodeScannerWithoutController
(),
),
...
...
ios/Classes/SwiftMobileScannerPlugin.swift
View file @
f2b103e
...
...
@@ -22,6 +22,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
// Image to be sent to the texture
var
latestBuffer
:
CVImageBuffer
!
// Return image buffer with the Barcode event
var
returnImage
:
Bool
=
false
// var analyzeMode: Int = 0
var
analyzing
:
Bool
=
false
var
position
=
AVCaptureDevice
.
Position
.
back
...
...
@@ -61,6 +64,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
stop
(
result
)
case
"analyzeImage"
:
analyzeImage
(
call
,
result
)
default
:
result
(
FlutterMethodNotImplemented
)
}
...
...
@@ -86,6 +90,16 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
return
Unmanaged
<
CVPixelBuffer
>.
passRetained
(
latestBuffer
)
}
private
func
ciImageToJpeg
(
ciImage
:
CIImage
)
->
Data
{
// let ciImage = CIImage(cvPixelBuffer: latestBuffer)
let
context
:
CIContext
=
CIContext
.
init
(
options
:
nil
)
let
cgImage
:
CGImage
=
context
.
createCGImage
(
ciImage
,
from
:
ciImage
.
extent
)
!
let
uiImage
:
UIImage
=
UIImage
(
cgImage
:
cgImage
,
scale
:
1
,
orientation
:
UIImage
.
Orientation
.
up
)
return
uiImage
.
jpegData
(
compressionQuality
:
0.8
)
!
;
}
// Gets called when a new image is added to the buffer
public
func
captureOutput
(
_
output
:
AVCaptureOutput
,
didOutput
sampleBuffer
:
CMSampleBuffer
,
from
connection
:
AVCaptureConnection
)
{
...
...
@@ -108,7 +122,13 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
scanner
.
process
(
image
)
{
[
self
]
barcodes
,
error
in
if
error
==
nil
&&
barcodes
!=
nil
{
for
barcode
in
barcodes
!
{
let
event
:
[
String
:
Any
?]
=
[
"name"
:
"barcode"
,
"data"
:
barcode
.
data
]
var
event
:
[
String
:
Any
?]
=
[
"name"
:
"barcode"
,
"data"
:
barcode
.
data
]
if
(
returnImage
&&
latestBuffer
!=
nil
)
{
let
image
:
CIImage
=
CIImage
(
cvPixelBuffer
:
latestBuffer
)
event
[
"image"
]
=
FlutterStandardTypedData
(
bytes
:
ciImageToJpeg
(
ciImage
:
image
))
}
sink
?(
event
)
}
}
...
...
@@ -168,6 +188,8 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
let
argReader
=
MapArgumentReader
(
call
.
arguments
as?
[
String
:
Any
])
returnImage
=
argReader
.
bool
(
key
:
"returnImage"
)
??
false
// let ratio: Int = argReader.int(key: "ratio")
let
torch
:
Bool
=
argReader
.
bool
(
key
:
"torch"
)
??
false
let
facing
:
Int
=
argReader
.
int
(
key
:
"facing"
)
??
1
...
...
lib/src/mobile_scanner_controller.dart
View file @
f2b103e
import
'dart:async'
;
import
'dart:io'
;
import
'dart:typed_data'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
...
...
@@ -44,6 +45,8 @@ class MobileScannerController {
late
final
ValueNotifier
<
CameraFacing
>
cameraFacingState
;
final
Ratio
?
ratio
;
final
bool
?
torchEnabled
;
// Whether to return the image buffer with the Barcode event
final
bool
returnImage
;
/// If provided, the scanner will only detect those specific formats.
///
...
...
@@ -65,6 +68,7 @@ class MobileScannerController {
this
.
torchEnabled
,
this
.
formats
,
this
.
autoResume
=
true
,
this
.
returnImage
=
false
,
})
{
// In case a new instance is created before calling dispose()
if
(
_controllerHashcode
!=
null
)
{
...
...
@@ -89,13 +93,15 @@ class MobileScannerController {
void
handleEvent
(
Map
event
)
{
final
name
=
event
[
'name'
];
final
data
=
event
[
'data'
];
switch
(
name
)
{
case
'torchState'
:
final
state
=
TorchState
.
values
[
data
as
int
?
??
0
];
torchState
.
value
=
state
;
break
;
case
'barcode'
:
final
barcode
=
Barcode
.
fromNative
(
data
as
Map
?
??
{});
final
image
=
returnImage
?
event
[
'image'
]
as
Uint8List
:
null
;
final
barcode
=
Barcode
.
fromNative
(
data
as
Map
?
??
{},
image
);
barcodesController
.
add
(
barcode
);
break
;
case
'barcodeMac'
:
...
...
@@ -169,6 +175,7 @@ class MobileScannerController {
arguments
[
'formats'
]
=
formats
!.
map
((
e
)
=>
e
.
rawValue
).
toList
();
}
}
arguments
[
'returnImage'
]
=
returnImage
;
// Start the camera with arguments
Map
<
String
,
dynamic
>?
startResult
=
{};
...
...
lib/src/objects/barcode.dart
View file @
f2b103e
...
...
@@ -12,6 +12,11 @@ class Barcode {
/// Returns null if the corner points can not be determined.
final
List
<
Offset
>?
corners
;
/// Returns raw bytes of the image buffer
///
/// Returns null if the image was not returned
final
Uint8List
?
image
;
/// Returns barcode format
final
BarcodeFormat
format
;
...
...
@@ -74,6 +79,7 @@ class Barcode {
Barcode
({
this
.
corners
,
this
.
image
,
this
.
format
=
BarcodeFormat
.
ean13
,
this
.
rawBytes
,
this
.
type
=
BarcodeType
.
text
,
...
...
@@ -91,7 +97,7 @@ class Barcode {
});
/// Create a [Barcode] from native data.
Barcode
.
fromNative
(
Map
data
)
Barcode
.
fromNative
(
Map
data
,
this
.
image
)
:
corners
=
toCorners
(
data
[
'corners'
]
as
List
?),
format
=
toFormat
(
data
[
'format'
]
as
int
),
rawBytes
=
data
[
'rawBytes'
]
as
Uint8List
?,
...
...
Please
register
or
login
to post a comment