Skip to content

[camera] add heif support image iOS #4586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 95 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 68 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
8c63615
add heic support image iOS
Mairramer Jul 29, 2023
78a86ec
format files
Mairramer Jul 29, 2023
a43d149
Merge branch 'main' into add-heic-support-ios
Mairramer Jul 29, 2023
88c7228
update version camera_platform_interface
Mairramer Jul 29, 2023
a90a81b
fix version
Mairramer Jul 29, 2023
a98c047
new test
Mairramer Jul 29, 2023
19b6ee2
update example
Mairramer Jul 29, 2023
44b7f43
refactor and adjusts code
Mairramer Jul 30, 2023
c67bf61
Update FLTCam_Test.h
Mairramer Jul 30, 2023
5f9a5fc
Update FLTCam.m
Mairramer Jul 30, 2023
88bb20d
Update CameraPlugin.m
Mairramer Jul 30, 2023
1e77287
new adjusts
Mairramer Jul 30, 2023
2abeabe
Update FLTCam.h
Mairramer Jul 30, 2023
d889f8b
Update CHANGELOG.md
Mairramer Jul 30, 2023
53a5838
fix versions
Mairramer Jul 30, 2023
89905f7
fix versions
Mairramer Jul 30, 2023
c748a86
fix versions to NEXT
Mairramer Jul 30, 2023
4d7b623
versions next section
Mairramer Jul 30, 2023
f0a42b2
Merge branch 'main' into add-heic-support-ios
Mairramer Jul 30, 2023
42cdd9d
fix tests
Mairramer Jul 31, 2023
897414f
Merge branch 'main' into add-heic-support-ios
Mairramer Aug 2, 2023
e7c21a1
Merge branch 'main' into add-heic-support-ios
Mairramer Aug 3, 2023
4ee2527
refactor code
Mairramer Aug 3, 2023
a446d01
added default value
Mairramer Aug 4, 2023
d5e261d
Merge remote-tracking branch 'origin/main' into add-heic-support-ios
Mairramer Oct 13, 2023
c5a812a
rebase main
Mairramer Oct 14, 2023
d15112e
fix header
Mairramer Oct 14, 2023
f906e99
format code
Mairramer Oct 14, 2023
2bad48f
Merge branch 'main' into add-heic-support-ios
Mairramer Oct 14, 2023
b6be5b5
add interface
Mairramer Oct 14, 2023
f57a9c2
fixes
Mairramer Oct 14, 2023
729b7a2
add interface
Mairramer Oct 14, 2023
d14f6cb
added test
Mairramer Oct 14, 2023
305c3b4
improves
Mairramer Oct 14, 2023
e62f6d2
rename extension
Mairramer Oct 15, 2023
4fc1da0
format
Mairramer Oct 15, 2023
3df56b3
refactor code
Mairramer Oct 18, 2023
3cb6af3
fix tests
Mairramer Oct 18, 2023
8564f1c
fix test
Mairramer Oct 18, 2023
cf53b1c
remove comment
Mairramer Oct 18, 2023
dc2fb21
code format
Mairramer Oct 18, 2023
c22989e
fix format
Mairramer Oct 18, 2023
a95ccef
format code
Mairramer Oct 18, 2023
97408df
fix format
Mairramer Oct 18, 2023
a5b8f1b
code improve
Mairramer Oct 19, 2023
1a39b9a
fix
Mairramer Oct 19, 2023
2b94bdb
improve code
Mairramer Oct 19, 2023
fb88b94
fix test
Mairramer Oct 19, 2023
59f1a10
format code
Mairramer Oct 20, 2023
383afa2
Merge branch 'main' into add-heic-support-ios
Mairramer Oct 20, 2023
7d9f5f5
fix mistake
Mairramer Oct 20, 2023
4bc9eb8
fix update android
Mairramer Oct 20, 2023
998d2b6
rename file
Mairramer Oct 20, 2023
441eb68
fix export
Mairramer Oct 20, 2023
c5ac5b6
update version
Mairramer Oct 20, 2023
0e55574
Merge branch 'main' into add-heic-support-ios
Mairramer Oct 20, 2023
6ad2422
refactor logic
Mairramer Oct 20, 2023
d728a4f
Merge branch 'main' into add-heic-support-ios
Mairramer Oct 20, 2023
4846d4a
improve code
Mairramer Oct 22, 2023
b010609
format code
Mairramer Oct 22, 2023
369aa1b
clang format
Mairramer Oct 23, 2023
f07bc24
next to camera
Mairramer Oct 23, 2023
c9f4df4
Merge branch 'main' into add-heic-support-ios
Mairramer Oct 23, 2023
b2ea23d
Merge branch 'main' into add-heic-support-ios
Mairramer Oct 23, 2023
eb49544
some changes
Mairramer Oct 31, 2023
73680ff
Merge branch 'main' into add-heic-support-ios
Mairramer Nov 1, 2023
23375ab
fix false positive tests
Mairramer Nov 1, 2023
0bdd96a
fix
Mairramer Nov 1, 2023
a7ede43
fix changelog
Mairramer Nov 2, 2023
7ae8540
fix tests
Mairramer Nov 3, 2023
5ed3a45
Merge branch 'main' into add-heic-support-ios
Mairramer Nov 17, 2023
c95d0f0
rename
Mairramer Nov 17, 2023
572eef1
Merge branch 'main' into add-heic-support-ios
Mairramer Nov 28, 2023
09e8f0a
new changes
Mairramer Nov 28, 2023
e271274
remove changes camera
Mairramer Nov 28, 2023
2338ac7
fix
Mairramer Nov 28, 2023
33b2dde
fix import
Mairramer Nov 28, 2023
df51b0b
new changes
Mairramer Nov 28, 2023
be233cb
fix
Mairramer Nov 28, 2023
f4b77ec
fix
Mairramer Nov 28, 2023
5cbb66b
new fixes
Mairramer Nov 29, 2023
4079924
format code
Mairramer Nov 29, 2023
9410af7
update some wording
bparrishMines Dec 5, 2023
d32d324
Merge branch 'main' of github.com:flutter/packages into add-heic-supp…
bparrishMines Dec 5, 2023
396a1bc
Merge branch 'main' into add-heic-support-ios
Mairramer Dec 22, 2023
344d22e
remove federated
Mairramer Dec 22, 2023
8bf202d
Merge branch 'main' into add-heic-support-ios
Mairramer Dec 28, 2023
0587ba5
Merge branch 'main' into add-heic-support-ios
Mairramer Jan 4, 2024
25b0676
Merge branch 'main' into add-heic-support-ios
Mairramer Jan 6, 2024
ebc79ba
Merge branch 'main' into add-heic-support-ios
Mairramer Jan 13, 2024
570db5f
Merge branch 'main' into add-heic-support-ios
Mairramer Jan 17, 2024
3d26f58
Merge branch 'main' into add-heic-support-ios
Mairramer Jan 19, 2024
feeff1f
Merge branch 'main' into add-heic-support-ios
Mairramer Jan 24, 2024
9588e3e
Update project.pbxproj
bparrishMines Jan 24, 2024
dbf5161
Merge branch 'main' into add-heic-support-ios
bparrishMines Jan 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/camera/camera/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## NEXT

* Adds support to HEIF format to iOS

## 0.10.5+5

* Fixes bug where old camera resources were not disposed when switching between camera descriptions.
Expand Down
25 changes: 25 additions & 0 deletions packages/camera/camera/example/integration_test/camera_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,29 @@ void main() {
},
skip: !Platform.isIOS,
);

testWidgets(
'Capture image with fileFormat',
(WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.isEmpty) {
return;
}
for (final CameraDescription cameraDescription in cameras) {
final CameraController controller =
CameraController(cameraDescription, ResolutionPreset.low);

await controller.setFileFormat(FileFormat.heif);
await controller.initialize();

final XFile file = await controller.takePicture();
final File fileImage = File(file.path);
final Image image =
await decodeImageFromList(fileImage.readAsBytesSync());

expect(image, isNotNull);
}
},
skip: !Platform.isIOS,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "The Flutter Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
5 changes: 5 additions & 0 deletions packages/camera/camera/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ dev_dependencies:

flutter:
uses-material-design: true

# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE.
# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins
dependency_overrides:
{camera_platform_interface: {path: ../../../camera/camera_platform_interface}}
3 changes: 2 additions & 1 deletion packages/camera/camera/lib/camera.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export 'package:camera_platform_interface/camera_platform_interface.dart'
FocusMode,
ResolutionPreset,
XFile,
ImageFormatGroup;
ImageFormatGroup,
FileFormat;

export 'src/camera_controller.dart';
export 'src/camera_image.dart';
Expand Down
19 changes: 19 additions & 0 deletions packages/camera/camera/lib/src/camera_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ class CameraController extends ValueNotifier<CameraValue> {
this.resolutionPreset, {
this.enableAudio = true,
this.imageFormatGroup,
this.fileFormat,
}) : super(CameraValue.uninitialized(description));

/// The properties of the camera device controlled by this controller.
Expand All @@ -258,6 +259,13 @@ class CameraController extends ValueNotifier<CameraValue> {
/// When null the imageFormat will fallback to the platforms default.
final ImageFormatGroup? imageFormatGroup;

/// The [FileFormat] describes the compression of the image.
///
/// When null the fileFormat will fallback [FileFormat.jpeg]
///
/// Only supported on iOS for now.
final FileFormat? fileFormat;

/// The id of a camera that hasn't been initialized.
@visibleForTesting
static const int kUninitializedCameraId = -1;
Expand Down Expand Up @@ -844,6 +852,17 @@ class CameraController extends ValueNotifier<CameraValue> {
}
}

/// Sets the output format for the camera.
///
/// If [format] is omitted, the default output format is used.
Future<void> setFileFormat(FileFormat format) async {
try {
await CameraPlatform.instance.setFileFormat(_cameraId, format);
} on PlatformException catch (e) {
throw CameraException(e.code, e.message);
}
}

/// Releases the resources of this camera.
@override
Future<void> dispose() async {
Expand Down
14 changes: 11 additions & 3 deletions packages/camera/camera/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing
Dart.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.10.5+5
version: 0.10.6

environment:
sdk: ">=2.19.0 <4.0.0"
Expand All @@ -22,8 +22,8 @@ flutter:

dependencies:
camera_android: ^0.10.7
camera_avfoundation: ^0.9.13
camera_platform_interface: ^2.5.0
camera_avfoundation: ^0.9.13+2
camera_platform_interface: ^2.5.1
camera_web: ^0.3.1
flutter:
sdk: flutter
Expand All @@ -39,3 +39,11 @@ dev_dependencies:

topics:
- camera

# FOR TESTING AND INITIAL REVIEW ONLY. DO NOT MERGE.
# See https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changing-federated-plugins
dependency_overrides:
{
camera_avfoundation: {path: ../../camera/camera_avfoundation},
camera_platform_interface: {path: ../../camera/camera_platform_interface},
}
6 changes: 6 additions & 0 deletions packages/camera/camera/test/camera_preview_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ class FakeController extends ValueNotifier<CameraValue>

@override
CameraDescription get description => value.description;

@override
FileFormat? get fileFormat => null;

@override
Future<void> setFileFormat(FileFormat format) async {}
}

void main() {
Expand Down
49 changes: 49 additions & 0 deletions packages/camera/camera/test/camera_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,50 @@ void main() {
'This is a test error message',
)));
});

test('setFileFormat() calls $CameraPlatform', () async {
final CameraController cameraController = CameraController(
const CameraDescription(
name: 'cam',
lensDirection: CameraLensDirection.front,
sensorOrientation: 90),
ResolutionPreset.max);
await cameraController.initialize();

await cameraController.setFileFormat(FileFormat.jpeg);

verify(CameraPlatform.instance
.setFileFormat(cameraController.cameraId, FileFormat.jpeg))
.called(1);
});

test('setFileFormat() throws $CameraException on $PlatformException',
() async {
final CameraController cameraController = CameraController(
const CameraDescription(
name: 'cam',
lensDirection: CameraLensDirection.front,
sensorOrientation: 90),
ResolutionPreset.max);
await cameraController.initialize();

when(CameraPlatform.instance
.setFileFormat(cameraController.cameraId, FileFormat.jpeg))
.thenThrow(
PlatformException(
code: 'TEST_ERROR',
message: 'This is a test error message',
),
);

expect(
cameraController.setFileFormat(FileFormat.jpeg),
throwsA(isA<CameraException>().having(
(CameraException error) => error.description,
'TEST_ERROR',
'This is a test error message',
)));
});
});
}

Expand Down Expand Up @@ -1554,6 +1598,11 @@ class MockCameraPlatform extends Mock
Invocation.method(#setExposureOffset, <Object?>[cameraId, offset]),
returnValue: Future<double>.value(1.0),
) as Future<double>;

@override
Future<void> setFileFormat(int cameraId, FileFormat format) async =>
super.noSuchMethod(
Invocation.method(#setFileFormat, <Object?>[cameraId, format]));
}

class MockCameraDescription extends CameraDescription {
Expand Down
4 changes: 4 additions & 0 deletions packages/camera/camera_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.9.14

* Adds support to HEIF format

## 0.9.13+7

* Fixes inverted orientation strings.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,25 @@ void main() {

expect(await completer.future, isNotNull);
});

// Test fileFormat is respected when taking a picture.
testWidgets('Capture specific image output formats',
(WidgetTester tester) async {
final List<CameraDescription> cameras =
await CameraPlatform.instance.availableCameras();
if (cameras.isEmpty) {
return;
}
for (final CameraDescription cameraDescription in cameras) {
for (final FileFormat fileFormat in FileFormat.values) {
final CameraController controller =
CameraController(cameraDescription, ResolutionPreset.low);
await controller.initialize();
await controller.setFileFormat(fileFormat);
final XFile file = await controller.takePicture();
await controller.dispose();
expect(file.path.endsWith(fileFormat.name()), true);
}
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
buildActionMask = 12;
files = (
);
inputPaths = (
Expand All @@ -386,7 +386,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
9872F2A25E8A171A111468CD /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
Expand Down Expand Up @@ -495,7 +495,11 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = RunnerTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "dev.flutter.plugins.cameraExample.camera-exampleTests";
Expand All @@ -521,7 +525,11 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = RunnerTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "dev.flutter.plugins.cameraExample.camera-exampleTests";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -648,7 +656,10 @@
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand All @@ -670,7 +681,10 @@
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,12 @@ - (void)testFLTGetStringForUIDeviceOrientation {
XCTAssertEqualObjects(@"portraitUp", FLTGetStringForUIDeviceOrientation(-1));
}

#pragma mark - file format tests

- (void)testFLTGetFileFormatForString {
XCTAssertEqual(FCPFileFormatJPEG, FCPGetFileFormatFromString(@"jpg"));
XCTAssertEqual(FCPFileFormatHEIF, FCPGetFileFormatFromString(@"heif"));
XCTAssertEqual(FCPFileFormatInvalid, FCPGetFileFormatFromString(@"unknown"));
}

@end
Loading