camera_extended
支持原生纵横比(16:9、4:3、1:1)的扩展Flutter相机插件。官方相机包的分支,支持传感器级别的纵横比配置。
Flutter 的 camera 插件的分支,支持原生宽高比(16:9、4:3、1:1)预览、照片和视频 —— Android 上使用 CameraX,iOS 上使用 AVFoundation。在 pub.dev 上名为 camera_extended。
以下为英文项目原文快照,最新内容请访问 GitHub。
Extended Flutter camera plugin with native aspect ratio support (16:9, 4:3, 1:1).
Fork of the official camera package with sensor-level aspect ratio configuration for both iOS and Android.
| Android | iOS | |
|---|---|---|
| Support | SDK 24+ | iOS 13.0+ |
| Feature | camera | camera_extended |
|---|---|---|
| Aspect Ratio Control | No | Yes (16:9, 4:3, 1:1) |
| Native 1:1 Square | No | Yes (Android) |
| Sensor-Level Config | No | Yes |
| In-Memory Capture | No | Yes (takePictureAsBytes()) |
| Video Stabilization | No | Yes (VideoStabilizationMode) |
takePictureAsBytes() returns raw Uint8List without saving to diskcamera package APIThe standard camera package doesn't allow you to configure the aspect ratio at the native level. This package extends it to:
| Ratio | Field of View | Use Case |
|---|---|---|
| 16:9 | Narrowest | Video, Widescreen |
| 4:3 | Wider | Photos, Standard |
| 1:1 | Square | Social Media, Profile Photos |
Add to your pubspec.yaml:
dependencies:
camera_extended: ^1.2.0
import 'package:camera_extended/camera_extended.dart';
late List<CameraDescription> cameras;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
runApp(MyApp());
}
final controller = CameraController(
cameras.first,
ResolutionPreset.high,
enableAudio: false,
aspectRatio: CameraAspectRatio.ratio4x3, // NEW: aspect ratio parameter
);
await controller.initialize();
enum CameraAspectRatio {
ratio16x9, // 16:9 widescreen
ratio4x3, // 4:3 standard
ratio1x1, // 1:1 square
ratioDefault, // Camera's default ratio
}
import 'package:camera_extended/camera_extended.dart';
import 'package:flutter/material.dart';
late List<CameraDescription> cameras;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
runApp(const CameraApp());
}
class CameraApp extends StatefulWidget {
const CameraApp({super.key});
@override
State<CameraApp> createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
CameraController? _controller;
CameraAspectRatio _aspectRatio = CameraAspectRatio.ratio4x3;
@override
void initState() {
super.initState();
_initCamera();
}
Future<void> _initCamera() async {
await _controller?.dispose();
_controller = CameraController(
cameras.first,
ResolutionPreset.high,
aspectRatio: _aspectRatio, // Set aspect ratio here
);
await _controller!.initialize();
if (mounted) setState(() {});
}
void _changeAspectRatio(CameraAspectRatio ratio) {
setState(() => _aspectRatio = ratio);
_initCamera(); // Reinitialize camera with new ratio
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: [
Expanded(
child: _controller?.value.isInitialized == true
? CameraPreview(_controller!)
: const Center(child: CircularProgressIndicator()),
),
Padding(
padding: const EdgeInsets.all(16),
child: SegmentedButton<CameraAspectRatio>(
segments: const [
ButtonSegment(value: CameraAspectRatio.ratio16x9, label: Text('16:9')),
ButtonSegment(value: CameraAspectRatio.ratio4x3, label: Text('4:3')),
ButtonSegment(value: CameraAspectRatio.ratio1x1, label: Text('1:1')),
],
selected: {_aspectRatio},
onSelectionChanged: (selected) => _changeAspectRatio(selected.first),
),
),
],
),
),
);
}
}
Capture an image directly as bytes without writing to disk — ideal for ML pipelines, image processing, or uploading:
final Uint8List bytes = await controller.takePictureAsBytes();
// Use bytes directly — no file I/O needed
Query supported stabilization modes and apply one:
// Check supported modes
final modes = await controller.getSupportedVideoStabilizationModes();
// Apply stabilization
await controller.setVideoStabilizationMode(VideoStabilizationMode.standard);
Available modes: off, standard, cinematic, cinematicExtended (availability depends on device).
| Platform | 16:9 | 4:3 | 1:1 |
|---|---|---|---|
| Android | Native | Native | Native (1088x1088) |
| iOS | Native | Native | Fallback to 4:3 |
Uses CameraX with ResolutionSelector to request specific aspect ratios. Many Android devices support native 1:1 formats (e.g., 1088x1088, 720x720).
Uses AVFoundation with format selection based on aspect ratio. iOS cameras typically don't offer native 1:1 formats, so 1:1 falls back to 4:3.
Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Add to Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is required for taking photos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access is required for recording video.</string>
camera PackageThis package is API-compatible with the original camera package. To migrate:
camera with camera_extended in pubspec.yamlimport 'package:camera_extended/camera_extended.dart'aspectRatio parameter to CameraController// Before (camera package)
import 'package:camera/camera.dart';
CameraController(camera, ResolutionPreset.high);
// After (camera_extended)
import 'package:camera_extended/camera_extended.dart';
CameraController(camera, ResolutionPreset.high, aspectRatio: CameraAspectRatio.ratio4x3);
Same as the original camera package - you need to handle lifecycle changes:
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
final CameraController? cameraController = controller;
if (cameraController == null || !cameraController.value.isInitialized) {
return;
}
if (state == AppLifecycleState.inactive) {
cameraController.dispose();
} else if (state == AppLifecycleState.resumed) {
_initCamera();
}
}
>=3.35.0^3.9.0| Package | Description |
|---|---|
| camera_extended | Main plugin (this package) |
| camera_extended_android | Android implementation |
| camera_extended_ios | iOS implementation |
| camera_extended_platform_interface | Platform interface |
BSD 3-Clause License - same as the original Flutter camera package.
Based on the official Flutter camera plugin by the Flutter team.
Extended with native aspect ratio support.
Made with love by Codigee
先按使用场景筛选,再比较项目活跃情况,最后到原始仓库核对使用要求。
“A repository is the most basic element of GitHub.”
GitHub Docs — About repositories ↗