Skip to content

Instantly share code, notes, and snippets.

@vivchar
Last active August 19, 2020 15:51
Show Gist options
  • Save vivchar/64d08b6e5b9b554d7ffdf1822bcb5087 to your computer and use it in GitHub Desktop.
Save vivchar/64d08b6e5b9b554d7ffdf1822bcb5087 to your computer and use it in GitHub Desktop.
// 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:math' as math;
import 'package:camera/camera.dart';
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gifimage/flutter_gifimage.dart';
import 'detector_painters.dart';
import 'scanner_utils.dart';
class CameraPreviewScanner extends StatefulWidget {
@override
State<StatefulWidget> createState() => _CameraPreviewScannerState();
}
class _CameraPreviewScannerState extends State<CameraPreviewScanner>
with TickerProviderStateMixin {
dynamic _scanResults;
double _y = 0.0;
double _z = 0.0;
CameraController _camera;
bool _isDetecting = false;
CameraLensDirection _direction = CameraLensDirection.back;
final FaceDetector _faceDetector = FirebaseVision.instance.faceDetector();
GifController controller;
@override
void initState() {
super.initState();
controller = GifController(vsync: this);
controller.repeat(
min: 0, max: 5, period: Duration(milliseconds: 300), reverse: true);
// controller.value = 0;
// controller.animateTo(5, duration: Duration(milliseconds: 600));
_initializeCamera();
}
void _initializeCamera() async {
final CameraDescription description =
await ScannerUtils.getCamera(_direction);
_camera = CameraController(
description,
defaultTargetPlatform == TargetPlatform.iOS
? ResolutionPreset.low
: ResolutionPreset.medium,
);
await _camera.initialize();
_camera.startImageStream((CameraImage image) {
if (_isDetecting) return;
_isDetecting = true;
// print("on image received");
ScannerUtils.detect(
image: image,
detectInImage: _faceDetector.processImage,
imageRotation: description.sensorOrientation,
).then(
(dynamic results) {
// print("on face detected");
setState(() {
_scanResults = results;
for (Face face in _scanResults) {
_z = face.headEulerAngleZ;
_y = face.headEulerAngleY;
break;
}
});
},
).whenComplete(() => _isDetecting = false);
});
}
Widget _buildResults() {
const Text noResultsText = Text('No results!');
if (_scanResults == null ||
_camera == null ||
!_camera.value.isInitialized) {
return noResultsText;
}
CustomPainter painter;
final Size imageSize = Size(
_camera.value.previewSize.height,
_camera.value.previewSize.width,
);
if (_scanResults is! List<Face>) return noResultsText;
painter = FaceDetectorPainter(imageSize, _scanResults);
return CustomPaint(
painter: painter,
);
}
Widget _buildImage() {
var halfW = MediaQuery.of(context).size.width / 2;
var correctedY = (_y / 45) * halfW;
print("correctedY=$correctedY, halfW $halfW, _y= $_y");
return Container(
constraints: const BoxConstraints.expand(),
child: _camera == null
? const Center(
child: Text(
'Initializing Camera...',
style: TextStyle(
color: Colors.green,
fontSize: 30.0,
),
),
)
: Stack(
fit: StackFit.expand,
children: <Widget>[
CameraPreview(_camera),
_buildResults(),
Positioned(
left: halfW + correctedY - 75,
top: MediaQuery.of(context).size.height * 0.7,
child: Transform.rotate(
angle: (-_z * math.pi / 180) * 1.5,
child: GifImage(
width: 150,
height: 150,
controller: controller,
image: AssetImage("assets/rocket.gif"),
),
),
)
],
),
);
}
void _toggleCameraDirection() async {
if (_direction == CameraLensDirection.back) {
_direction = CameraLensDirection.front;
} else {
_direction = CameraLensDirection.back;
}
await _camera.stopImageStream();
await _camera.dispose();
setState(() {
_camera = null;
});
_initializeCamera();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildImage(),
floatingActionButton: FloatingActionButton(
onPressed: _toggleCameraDirection,
child: _direction == CameraLensDirection.back
? const Icon(Icons.camera_front)
: const Icon(Icons.camera_rear),
),
);
}
@override
void dispose() {
_camera.dispose().then((_) {
_faceDetector.close();
});
super.dispose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment