[camera_android, camera_android_camerax, camera_avfoundation] Add setJpegImageQuality#11616
[camera_android, camera_android_camerax, camera_avfoundation] Add setJpegImageQuality#11616Bolling88 wants to merge 2 commits intoflutter:mainfrom
Conversation
Adds setJpegImageQuality(int quality) across all camera platform implementations (Android, Android CameraX, iOS AVFoundation) and the app-facing camera package. This allows controlling the JPEG compression quality (1-100) for still image capture. Platform interface changes were landed separately in flutter#11454.
There was a problem hiding this comment.
Code Review
This pull request adds the setJpegImageQuality method to the CameraController and implements it across the Android (Camera2 and CameraX) and iOS (AVFoundation) platform packages. Review feedback identifies a potential ClassCastException in the Android Camera2 implementation due to an incorrect type cast, the loss of flashMode state when recreating the ImageCapture use case in CameraX, and the unintended discarding of capture configurations in the iOS implementation.
|
|
||
| @Override | ||
| public void updateBuilder(@NonNull CaptureRequest.Builder requestBuilder) { | ||
| requestBuilder.set(CaptureRequest.JPEG_QUALITY, (byte) currentSetting); |
There was a problem hiding this comment.
The CaptureRequest.JPEG_QUALITY key expects an Integer value (type Key<Integer>). Casting currentSetting to byte will result in a Byte object being passed to the requestBuilder.set method due to autoboxing. This will cause a ClassCastException at runtime because a Byte cannot be cast to an Integer.
| requestBuilder.set(CaptureRequest.JPEG_QUALITY, (byte) currentSetting); | |
| requestBuilder.set(CaptureRequest.JPEG_QUALITY, currentSetting); |
| imageCapture = ImageCapture( | ||
| resolutionSelector: _presetResolutionSelector, | ||
| targetRotation: targetRotation, | ||
| jpegQuality: quality, | ||
| ); |
There was a problem hiding this comment.
When recreating the ImageCapture instance to apply the new JPEG quality, the current flashMode is not passed to the constructor. This will cause the camera's flash setting to be reset to its default value whenever setJpegImageQuality is called.
imageCapture = ImageCapture(
resolutionSelector: _presetResolutionSelector,
targetRotation: targetRotation,
flashMode: flashMode,
jpegQuality: quality,
);| settings = AVCapturePhotoSettings(format: [ | ||
| AVVideoCodecKey: AVVideoCodecType.jpeg, | ||
| AVVideoCompressionPropertiesKey: [ | ||
| AVVideoQualityKey: CGFloat(imageQuality) / 100.0 | ||
| ], | ||
| ]) |
There was a problem hiding this comment.
Reassigning the settings variable here discards any configuration previously applied to the AVCapturePhotoSettings object. For example, settings like photoQualityPrioritization (which is typically set at the beginning of the takePicture method in this plugin) will be lost when imageQuality < 100. It is recommended to initialize settings with the correct format at the start of the takePicture method instead of reassigning it mid-flow.
The app-facing camera package should be submitted as a separate follow-up PR after the implementation packages are published. This removes the dependency_overrides that were blocking merge.
Implements the
setJpegImageQualityAPI (landed in the platform interface via #11454) across all camera platform implementation packages, allowing control of JPEG compression quality (1-100) for still image capture.This is the follow-up implementation PR as requested in #11155; it does not include
camera_platform_interfacechanges. The app-facingcamerapackage will be submitted in a separate PR after these implementation packages are published.Packages changed:
camera_androidcamera_android_cameraxcamera_avfoundationPart of flutter/flutter#183229
Pre-Review Checklist
[shared_preferences]///).Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2