Skip to content

[image_picker] Fix scaling 10-bit images - #12557

Merged
auto-submit[bot] merged 8 commits into
flutter:mainfrom
0xthk:fix/image-picker-ios-10-bit
Sep 23, 2026
Merged

auto-submit[bot] merged 8 commits into
flutter:mainfrom
0xthk:fix/image-picker-ios-10-bit

Conversation

@0xthk

@0xthk 0xthk commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor

Resizing a 10-bit wide-gamut UIImage can carry its source renderer format into UIGraphicsImageRenderer. On iOS 26 this can request an unsupported 10-bit integer bitmap context, producing a zero-size image and an empty XFile after JPEG conversion.

This change renders scaled images with a standard-range format while preserving the source scale and opacity. The native regression test synthesizes a Display-P3 kCIFormatRGB10 image and verifies that the same 1920-pixel and JPEG-quality path produces a non-empty, decodable image.

Fixes flutter/flutter#185623.

Tests

  • dart run script/tool/bin/flutter_plugin_tools.dart format --packages=image_picker_ios
  • dart run script/tool/bin/flutter_plugin_tools.dart analyze --packages=image_picker_ios
  • dart run script/tool/bin/flutter_plugin_tools.dart dart-test --packages=image_picker_ios
  • dart run script/tool/bin/flutter_plugin_tools.dart native-test --ios --no-integration --packages=image_picker_ios
  • Focused native regression test verified failing before the production change and passing afterward on an iPhone 17 simulator running iOS 26.

Pre-Review Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the AI contribution guidelines and understand my responsibilities.
  • I read the Tree Hygiene page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter.
  • I signed the CLA. Awaiting confirmation from the CLA bot.
  • The title of the PR starts with the name of the package surrounded by square brackets.
  • I linked to at least one issue that this PR fixes in the description above.
  • I followed the version and CHANGELOG instructions, using semantic versioning and the repository CHANGELOG style.
  • I updated or added any relevant documentation. There is no public API change requiring API documentation.
  • I added new tests to check the change I am making.
  • All existing and new tests are passing.

Using the source UIImage renderer format can create an unsupported 10-bit integer bitmap context, which produces an empty image during resizing.

Render scaled images with a standard-range format while preserving scale and opacity so the result remains encodable.
@google-cla

google-cla Bot commented Aug 23, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the iOS image picker implementation to fix scaling of 10-bit images by setting the preferredRange of UIGraphicsImageRendererFormat to UIGraphicsImageRendererFormatRangeStandard. A unit test is added to verify that a 10-bit wide gamut image can be scaled and encoded as a JPEG. The review feedback suggests adding a nil check for cgImage in the new test to prevent a potential crash when calling CGImageGetBitsPerComponent if the image creation fails.

Comment on lines +258 to +259
XCTAssertNotEqual(cgImage, nil);
XCTAssertEqual(CGImageGetBitsPerComponent(cgImage), 10);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If cgImage fails to create and returns nil (for example, if the test environment or simulator does not support the kCIFormatRGB10 format), the test runner will crash when calling the CoreGraphics C function CGImageGetBitsPerComponent(cgImage) because C functions do not have nil safety. To prevent test suite crashes, we should check if cgImage is nil and return early after releasing the color space.

Suggested change
XCTAssertNotEqual(cgImage, nil);
XCTAssertEqual(CGImageGetBitsPerComponent(cgImage), 10);
XCTAssertNotEqual(cgImage, nil);
if (cgImage == nil) {
CGColorSpaceRelease(displayP3ColorSpace);
return;
}
XCTAssertEqual(CGImageGetBitsPerComponent(cgImage), 10);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 8dca11c. The assertion still records the setup failure, and the early return prevents passing a null CGImageRef to Core Graphics.

@0xthk 0xthk changed the title [image_picker_ios] Fix scaling 10-bit images [image_picker] Fix scaling 10-bit images Aug 25, 2026
@Piinks Piinks added the triage-ios Should be looked at in iOS triage label Aug 25, 2026

@LouiseHsu LouiseHsu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm!

…s-10-bit

# Conflicts:
#	packages/image_picker/image_picker_ios/CHANGELOG.md
#	packages/image_picker/image_picker_ios/example/ios/RunnerTests/ImageUtilTests.m
@LongCatIsLooong

Copy link
Copy Markdown
Contributor

/cc @hellohuanlin

UIGraphicsImageRendererFormat *imageRendererFormat = [[UIGraphicsImageRendererFormat alloc] init];
imageRendererFormat.scale = imageToScale.imageRendererFormat.scale;
imageRendererFormat.opaque = imageToScale.imageRendererFormat.opaque;
imageRendererFormat.preferredRange = UIGraphicsImageRendererFormatRangeStandard;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment explaining the fix here? Otherwise future contributor may try to clean this up back into the original buggy behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 13b99f0. The comment explains that reusing the source format can request an unsupported 10-bit integer bitmap context and produce an empty scaled image, which is why we create a fresh standard-range format while preserving scale and opacity.

@vashworth vashworth added autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD labels Sep 21, 2026
@auto-submit

auto-submit Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/packages/12557, because - The status or check suite ci.yaml validation has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 21, 2026
@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Sep 22, 2026
@tarrinneal tarrinneal added CICD Run CI/CD autosubmit Merge PR when tree becomes green via auto submit App labels Sep 23, 2026
@auto-submit
auto-submit Bot merged commit 0851c39 into flutter:main Sep 23, 2026
13 checks passed
pull Bot pushed a commit to edisplay/flutter that referenced this pull request Sep 24, 2026
…er#193289)

Roll Packages from c2b58e1a97fb to 431ea69a42e2 (56 revisions)

flutter/packages@c2b58e1...431ea69

2026-09-24 [email protected] [cross_file]
Updates cross_file to a package separated federated plugin
(flutter/packages#11010)
2026-09-23 [email protected] [material_ui]
Remove static access of `copyWith` from `dart fix` golden tests for
`ThemeData/TextTheme` (flutter/packages#12994)
2026-09-23 [email protected] [camera_avfoundation] Replace
deprecated high-resolution capture APIs (flutter/packages#12372)
2026-09-23 [email protected] [pigeon] update nullish checks to use
new isNullish method (flutter/packages#12985)
2026-09-23 [email protected] [ci] Assign batch release PR approver
as reviewer on sync-back PR (flutter/packages#12976)
2026-09-23 [email protected] [image_picker] Fix scaling 10-bit images
(flutter/packages#12557)
2026-09-23 [email protected] [material_ui] Improve
Autocomplete, DrawerHeader, and Tooltip accessibility
(flutter/packages#12918)
2026-09-23 [email protected] [google_fonts] Decouple GoogleFontsLite
for full tree-shaking and add full feature parity
(flutter/packages#12830)
2026-09-23 [email protected] [file_selector]
Ignore flakey `file_selector_android` tests (flutter/packages#12992)
2026-09-23 [email protected] [CI] Remove
bringup from `Mac_arm64 build_all_packages` targets
(flutter/packages#12978)
2026-09-22 [email protected] [material_ui]
Unskip 5 passing web tests in bottom_app_bar_test and text_field_test
(flutter/packages#12983)
2026-09-22 [email protected]
[cupertino_ui] Unskip 5 passing web tests in
adaptive_text_selection_toolbar_test and text_field_test
(flutter/packages#12984)
2026-09-22 [email protected] [go_router] Fix ShellRoute chrome dropped
from semantics tree by ModalBarrier (flutter/packages#12353)
2026-09-22 [email protected] [material_ui]
Add contrastLevel for M3 ColorScheme (flutter/packages#12743)
2026-09-22 [email protected] [go_router] Preserve nested pushes
during config updates (flutter/packages#12611)
2026-09-22 [email protected] [material_ui]
Migrate M3 Chip template to use new gen_defaults
(flutter/packages#12847)
2026-09-22 [email protected] [material_ui] Fix
LocalHistoryEntry leak when double tapping Drawer scrim
(flutter/packages#12552)
2026-09-22 [email protected] Update suggested reviewers
(flutter/packages#12974)
2026-09-22 [email protected] Sync release-material_ui-1.4.0 to
main (flutter/packages#12966)
2026-09-22 [email protected] Sync release-cupertino_ui-1.1.1 to
main (flutter/packages#12965)
2026-09-21 [email protected] [ci] Update repo
for 3.47 stable release (flutter/packages#12959)
2026-09-21 [email protected] Manual roll Flutter from
27fec0e to 4fcd90b (1 revision) (flutter/packages#12904)
2026-09-21 [email protected] Revert "[go_router_builder] Migrate to
material_ui" (flutter/packages#12962)
2026-09-21 [email protected]
[material_ui] Update `material_ui` tests to prevent them from failing
when framework `TextStyle` changes (flutter/packages#12728)
2026-09-21 [email protected] [go_router_builder] Migrate to
material_ui (flutter/packages#12913)
2026-09-21 [email protected] [material_ui,
cupertino_ui] Bump Flutter version from to 3.47 (flutter/packages#12944)
2026-09-21 [email protected] [cupertino_ui] Work around dart2wasm
optional parameter inference bug in example checkbox tests
(flutter/packages#12961)
2026-09-21 [email protected] [cupertino_ui] Work around dart2wasm
optional parameter inference bug in checkbox_test.dart
(flutter/packages#12956)
2026-09-21 [email protected] [google_sign_in] PR 3/4 Migrate
ViewProvider and GID SDK wrappers from Objective-C to Swift
(flutter/packages#12657)
2026-09-21 [email protected] [google_sign_in] PR 2/4 Migrate
the plugin class from Objective-C to Swift. (flutter/packages#12655)
2026-09-20 [email protected]
[cross_file_darwin] iOS/macOS implementation of `cross_file`
(flutter/packages#12910)
2026-09-20 [email protected]
[cross_file_web] Web implementation of `cross_file`
(flutter/packages#12908)
2026-09-20 [email protected] [material_ui]
Migrate M3 `InputChip` template to use new gen_defaults
(flutter/packages#12850)
2026-09-20 [email protected] [material_ui]
Migrate M3 Checkbox defaults to new gen_defaults
(flutter/packages#12816)
2026-09-20 [email protected] [material_ui]
Migrate M3 `FilterChip` template to use new gen_defaults
(flutter/packages#12849)
2026-09-19 [email protected] [material_ui] Announce PopupMenuButton with a
child as a button (flutter/packages#12585)
2026-09-19 [email protected] Roll Flutter (stable) from
9584c67 to 6a19cca (7 revisions) (flutter/packages#12950)
2026-09-18 [email protected] [material_ui]
Reduce the `material_ui` non-wasm web test suite
(flutter/packages#12763)
2026-09-18 [email protected] Replace
`Mac_x64` builders with `Mac_arm64` ones (flutter/packages#12941)
2026-09-18 [email protected]
[in_app_purchase_storekit] Use `_$SKPaymentDiscountWrapperToJson`
(flutter/packages#12721)
2026-09-18 [email protected] [In_app _purchase] README
excerpt examples and changelog (flutter/packages#12739)
2026-09-18 [email protected] [material_ui] Add alternative
input method for `RangeSlider` in `NavigationMode.directional`
(flutter/packages#12630)
2026-09-18 [email protected]
[cross_file_android] Android implementation of `cross_file`
(flutter/packages#12909)
2026-09-18 [email protected]
[camera_platform_interface] Adds videoOutputPath support to
startVideoRecording (flutter/packages#12667)
2026-09-17 [email protected] [cupertino_ui] Migrate a
snippet in `CupertinoCheckbox`'s API doc to `{@example}` and add unit
tests (flutter/packages#12180)
2026-09-17 [email protected] [material_ui]
Default gen_defaults color helper prefix (flutter/packages#12848)
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD p: image_picker platform-ios triage-ios Should be looked at in iOS triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[image_picker] pickImage fails on image with markups on iOS 26

7 participants