Skip to content

[camera_android_camerax] ResolutionPreset.max does not select Camera2 high-resolution JPEG still capture sizes #188310

Description

@kalyujniy

Steps to reproduce

  1. Use camera with ResolutionPreset.max on an affected Android device.
  2. Call takePicture().

Expected results

Still capture uses the highest available JPEG resolution supported by the device.

Actual results

Still capture uses a lower regular JPEG resolution.

Code sample

Code sample
import 'dart:io';
import 'dart:ui' as ui;

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final cameras = await availableCameras();
  runApp(CameraMaxResolutionBugApp(cameras: cameras));
}

class CameraMaxResolutionBugApp extends StatelessWidget {
  const CameraMaxResolutionBugApp({super.key, required this.cameras});

  final List<CameraDescription> cameras;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: cameras.isEmpty
          ? const Scaffold(
              body: Center(child: Text('No cameras found on this device.')),
            )
          : CameraMaxResolutionPage(
              camera: cameras.firstWhere(
                (camera) => camera.lensDirection == CameraLensDirection.back,
                orElse: () => cameras.first,
              ),
            ),
    );
  }
}

class CameraMaxResolutionPage extends StatefulWidget {
  const CameraMaxResolutionPage({super.key, required this.camera});

  final CameraDescription camera;

  @override
  State<CameraMaxResolutionPage> createState() => _CameraMaxResolutionPageState();
}

class _CameraMaxResolutionPageState extends State<CameraMaxResolutionPage> {
  CameraController? _controller;
  String? _status;
  String? _captureSize;

  @override
  void initState() {
    super.initState();
    _initializeCamera();
  }

  Future<void> _initializeCamera() async {
    final controller = CameraController(
      widget.camera,
      ResolutionPreset.max,
      enableAudio: false,
    );

    await controller.initialize();
    if (!mounted) return;

    setState(() {
      _controller = controller;
      _status = 'Preview size: ${controller.value.previewSize}';
    });
  }

  Future<void> _takePicture() async {
    final controller = _controller;
    if (controller == null || !controller.value.isInitialized) return;

    final file = await controller.takePicture();
    final bytes = await File(file.path).readAsBytes();
    final codec = await ui.instantiateImageCodec(bytes);
    final frame = await codec.getNextFrame();
    final width = frame.image.width;
    final height = frame.image.height;
    frame.image.dispose();

    debugPrint('takePicture() output size: ${width}x$height');

    if (!mounted) return;
    setState(() {
      _captureSize = '${width}x$height';
      _status = 'Capture complete.';
    });
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final controller = _controller;

    return Scaffold(
      appBar: AppBar(title: const Text('ResolutionPreset.max repro')),
      body: Column(
        children: [
          Expanded(
            child: controller == null || !controller.value.isInitialized
                ? const Center(child: CircularProgressIndicator())
                : CameraPreview(controller),
          ),
          Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('Preset: ResolutionPreset.max'),
                if (_status != null) Text(_status!),
                if (_captureSize != null) Text('Captured image size: $_captureSize'),
                const SizedBox(height: 16),
                FilledButton(
                  onPressed: controller?.value.isInitialized == true ? _takePicture : null,
                  child: const Text('Take picture'),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
takePicture() output size: 2448x3264

Camera2 regular JPEG max: 3264x2448
Camera2 high-resolution JPEG: 4624x3468
Device: RMX3472, Android 14 (API 34)
Related PR: flutter/packages#11956

Flutter Doctor output

[✓] Flutter (Channel stable, 3.44.2, on macOS 26.5.1 25F80 darwin-arm64, locale en-US) [517ms]
• Flutter version 3.44.2 on channel stable at /Users/kirillkaluznyj/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision c9a6c48 (12 days ago), 2026-06-10 15:52:41 -0700
• Engine revision 77e2e94
• Dart version 3.12.2
• DevTools version 2.57.0
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, enable-swift-package-manager, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0) [1,914ms]
• Android SDK at /Users/kirillkaluznyj/Library/Android/sdk
• Emulator version 36.3.10.0 (build_id 14472402) (CL:N/A)
• Platform android-36, build-tools 36.1.0
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
This is the JDK bundled with the latest Android Studio installation on this machine.
To manually set the JDK path, use: flutter config --jdk-dir="path/to/jdk".
• Java version OpenJDK Runtime Environment (build 21.0.8+-14196175-b1038.72)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 26.5) [992ms]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 17F42
• CocoaPods version 1.16.2
[✓] Chrome - develop for the web [3ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Connected device (4 available) [6.5s]
• RMX3472 (mobile) • 3c8f23d4 • android-arm64 • Android 14 (API 34)
• macOS (desktop) • macos • darwin-arm64 • macOS 26.5.1 25F80 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 149.0.7827.155
! Error: Browsing on the local area network for Кирилл Калюжный’s iPad. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources [254ms]
• All expected network resources are available.
• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listhas reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: cameraThe camera pluginpackageflutter/packages repository. See also p: labels.platform-androidAndroid applications specificallyteam-androidOwned by Android platform teamtriaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    Status
    [Non-blocking] Issues

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions