manual_camera_view 0.1.1
manual_camera_view: ^0.1.1 copied to clipboard
A lightweight Flutter plugin for embedding a native camera preview with tap focus, normalized exposure control, and JPEG capture.
import 'package:flutter/material.dart';
import 'package:manual_camera_view/manual_camera.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CameraPage(),
);
}
}
/// 相机页面组件
class CameraPage extends StatefulWidget {
const CameraPage({
Key? key,
}) : super(key: key);
@override
State<CameraPage> createState() => _CameraPageState();
}
class _CameraPageState extends State<CameraPage> {
final ManualCameraController _controller = ManualCameraController();
bool _hasCameraPermission = false;
bool _isCheckingPermission = true;
bool _isCapturing = false;
double _exposure = 0.0;
// 文件长度
// int _fileLength = 0;
// 图片质量(1~100):值越高画质越好、体积越大
int _imageQuality = 100;
@override
void initState() {
super.initState();
_requestCameraPermission();
}
Future<void> _requestCameraPermission() async {
final status = await Permission.camera.request();
if (!mounted) return;
setState(() {
_hasCameraPermission = status.isGranted;
_isCheckingPermission = false;
});
}
void _onViewCreated() {
setState(() {});
}
/// 拍照处理(示例:连拍7张)
Future<void> _onTakePicture() async {
if (!_controller.isReady || _isCapturing) return;
setState(() {
_isCapturing = true;
});
try {
// 拍照前先把当前图片质量设置到原生
await _controller.setImageQuality(_imageQuality);
// 示例:连拍7张照片
for (var i = 0; i < 7; i++) {
final bytes = await _controller.takePicture();
// 这里可以处理每张照片,例如上传到服务器
// upload(bytes);
// _fileLength += bytes.length;
debugPrint('captured bytes: ${bytes.length}');
debugPrint('waiting 200ms before next capture');
await Future.delayed(const Duration(milliseconds: 200));
}
} finally {
if (mounted) {
setState(() {
_isCapturing = false;
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("相机"),
),
body: _isCheckingPermission
? const Center(child: CircularProgressIndicator())
: !_hasCameraPermission
? Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('未获取相机权限,请先允许访问相机'),
const SizedBox(height: 12),
ElevatedButton(
onPressed: _requestCameraPermission,
child: Text('重新申请权限'),
),
],
),
)
: Column(
children: [
Expanded(
child: Stack(
children: [
ManualCameraView(
controller: _controller,
onViewCreated: _onViewCreated,
),
if (_controller.isReady)
Positioned(
left: 0,
top: 230,
child: Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 曝光调节滑杆
RotatedBox(
quarterTurns: -1,
child: Slider(
min: -1.0,
max: 1.0,
value: _exposure,
onChanged: (value) {
setState(() => _exposure = value);
_controller
.setNormalizedExposure(value);
},
),
),
// const SizedBox(height: 8),
// 图片质量调节(1~100)
// SizedBox(
// width: 140,
// child: Column(
// children: [
// Text('质量: $_imageQuality'),
// Slider(
// min: 1,
// max: 100,
// divisions: 99,
// value: _imageQuality.toDouble(),
// onChanged: (value) {
// print(value);
// setState(() => _imageQuality = value.round());
// },
// ),
// ],
// ),
// ),
],
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(16),
child: ElevatedButton(
onPressed: _isCapturing ? null : _onTakePicture,
child: _isCapturing
? const SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
AlwaysStoppedAnimation<Color>(
Colors.white),
),
)
: Icon(Icons.camera_alt),
),
),
),
],
),
),
],
),
);
}
}