我已经使用camera
包创建了一个相机处理程序。结果看起来像这样:
我希望在捕获的图像中包括时钟和用户配置文件(捕获和后退按钮除外)之类的叠加层,可以这样做吗?
或者也许我应该使用带有条件的屏幕截图,而不是使用捕获功能?
谢谢!
编辑
这是我的camera.dart
的样子:
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
List<CameraDescription> cameras;
class CameraPage extends StatefulWidget {
final int cameraIdx;
CameraPage({
Key key,
@required this.cameraIdx,
}) : super(key: key);
@override
_CameraPageState createState() => _CameraPageState();
}
class _CameraPageState extends State<CameraPage> {
CameraController controller;
List cameras;
int selectedCameraIdx;
String imagePath;
String _timeString;
Timer _timer;
void _getTime() {
final DateTime now = DateTime.now();
final String formattedDateTime = _formatDateTime(now);
setState(() {
_timeString = formattedDateTime;
});
}
String _formatDateTime(DateTime dateTime) =>
DateFormat('HH:mm:ss').format(dateTime);
String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
// Initialize camera controller
Future _initCameraController(CameraDescription cameraDescription) async {
if (controller != null) {
await controller.dispose();
}
// set controller by the camera description with high resolution preset
controller = CameraController(cameraDescription, ResolutionPreset.high);
// If the controller is updated then update the UI.
controller.addListener(() {
// when this widget is mounted clear the state
if (this.mounted) {
setState(() {});
}
if (controller.value.hasError) {
print('Camera error ${controller.value.errorDescription}');
}
});
// 6
try {
await controller.initialize();
} on CameraException catch (e) {
print(e);
}
if (this.mounted) {
setState(() {});
}
}
Future<String> takePicture() async {
if (!controller.value.isInitialized) {
return null;
}
final Directory extDir = await getExternalStorageDirectory();
final String dirPath = '${extDir.path}/Pictures/flutter_test';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.jpg';
if (controller.value.isTakingPicture) {
// A capture is already pending, do nothing.
return null;
}
try {
await controller.takePicture(filePath);
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
return filePath;
}
void logError(String code, String message) =>
print('Error: $code\nError Message: $message');
void _showCameraException(CameraException e) {
logError(e.code, e.description);
}
void onCaptureButtonPressed() {
takePicture().then((String filePath) {
print(filePath);
if (mounted) {
setState(() {
imagePath = filePath;
});
}
});
}
@override
void initState() {
super.initState();
// Check if camera available
availableCameras().then((availableCameras) {
cameras = availableCameras;
if (cameras.length > 0) {
setState(() {
// Select front camera as default
if (widget.cameraIdx != null) {
selectedCameraIdx = widget.cameraIdx;
} else {
selectedCameraIdx = 1;
}
});
_initCameraController(cameras[selectedCameraIdx]).then((void v) {});
} else {
print("No camera available");
}
}).catchError((err) {
// Print error if any
print('Error: $err.code\nError Message: $err.message');
});
_timeString = _formatDateTime(DateTime.now());
_timer = Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime());
}
@override
void dispose() {
controller?.dispose();
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
if (!controller.value.isInitialized) {
return Container();
}
return Scaffold(
body: Stack(
children: <Widget>[
Transform.scale(
scale: controller.value.aspectRatio / deviceRatio,
child: Center(
child: AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
),
),
),
Align(
alignment: Alignment.topCenter,
child: Container(
width: double.infinity,
height: 110.0,
padding: EdgeInsets.only(right: 20.0),
child: Padding(
padding: EdgeInsets.only(top: 40.0, right: 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
GestureDetector(
child: Padding(
padding: EdgeInsets.only(left: 20.0),
child: Icon(
FontAwesomeIcons.arrowLeft,
color: Colors.white,
size: 30.0,
),
),
onTap: () {
Navigator.of(context).pop();
},
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 15.0, right: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text('Donny Pratama',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.0)),
Text(
'Front End Developer',
style: TextStyle(color: Colors.white),
)
],
),
),
CircleAvatar(
radius: 30.0,
backgroundImage:
NetworkImage('https://via.placeholder.com/150'),
backgroundColor: Colors.transparent,
)
],
),
],
),
),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Container(
width: double.infinity,
height: 180.0,
padding: EdgeInsets.only(left: 20.0),
child: Align(
alignment: Alignment.topLeft,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
_timeString,
style: TextStyle(
color: Colors.white,
fontSize: 50.0,
fontFamily: 'Roboto',
),
),
Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: 5.0),
child: Icon(
FontAwesomeIcons.mapMarkerAlt,
color: Colors.white,
size: 12.0,
),
),
Text(
'Yogyakarta, Indonesia',
style: TextStyle(color: Colors.white),
)
],
),
],
),
],
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity,
height: 120.0,
// color: Colors.white,
padding: EdgeInsets.all(20.0),
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: SizedBox(
width: double.infinity,
height: 60.0,
child: RaisedButton(
elevation: 0.5,
color: Colors.orange,
textColor: Colors.white,
child: Icon(FontAwesomeIcons.camera),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
onPressed: onCaptureButtonPressed,
),
),
),
],
),
),
),
],
),
);
}
}