Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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/image_picker/image_picker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.8.4+4

* Support adding WebP for iOS
Comment thread
TrGiLong marked this conversation as resolved.
Outdated

## 0.8.4+3

* Suppress a unchecked cast build warning.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
680049382280F2B9006DD6AB /* pngImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 680049352280F2B8006DD6AB /* pngImage.png */; };
680049392280F2B9006DD6AB /* jpgImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 680049362280F2B8006DD6AB /* jpgImage.jpg */; };
6801C8392555D726009DAF8D /* ImagePickerFromGalleryUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6801C8382555D726009DAF8D /* ImagePickerFromGalleryUITests.m */; };
86E9A890272747C00017E6E0 /* webpImage.webp in Resources */ = {isa = PBXBuildFile; fileRef = 86E9A88F272747B90017E6E0 /* webpImage.webp */; };
86E9A89127274A360017E6E0 /* webpImage.webp in Resources */ = {isa = PBXBuildFile; fileRef = 86E9A88F272747B90017E6E0 /* webpImage.webp */; };
86E9A893272754860017E6E0 /* PickerSaveImageToPathOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 86E9A892272754860017E6E0 /* PickerSaveImageToPathOperationTests.m */; };
86E9A894272754A30017E6E0 /* webpImage.webp in Resources */ = {isa = PBXBuildFile; fileRef = 86E9A88F272747B90017E6E0 /* webpImage.webp */; };
86E9A895272769130017E6E0 /* pngImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 680049352280F2B8006DD6AB /* pngImage.png */; };
Comment thread
cyanglaz marked this conversation as resolved.
86E9A896272769150017E6E0 /* jpgImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 680049362280F2B8006DD6AB /* jpgImage.jpg */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
Expand Down Expand Up @@ -82,6 +88,8 @@
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
86E9A88F272747B90017E6E0 /* webpImage.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = webpImage.webp; sourceTree = "<group>"; };
86E9A892272754860017E6E0 /* PickerSaveImageToPathOperationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PickerSaveImageToPathOperationTests.m; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -139,6 +147,7 @@
F78AF3172342D9D7008449C7 /* ImagePickerTestImages.h */,
F78AF3182342D9D7008449C7 /* ImagePickerTestImages.m */,
68B9AF71243E4B3F00927CE4 /* ImagePickerPluginTests.m */,
86E9A892272754860017E6E0 /* PickerSaveImageToPathOperationTests.m */,
334733F62668136400DCC49E /* Info.plist */,
);
path = RunnerTests;
Expand All @@ -147,6 +156,7 @@
680049282280E33D006DD6AB /* TestImages */ = {
isa = PBXGroup;
children = (
86E9A88F272747B90017E6E0 /* webpImage.webp */,
9FC8F0E8229FA49E00C8D58F /* gifImage.gif */,
680049362280F2B8006DD6AB /* jpgImage.jpg */,
680049352280F2B8006DD6AB /* pngImage.png */,
Expand Down Expand Up @@ -373,6 +383,9 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
86E9A894272754A30017E6E0 /* webpImage.webp in Resources */,
86E9A895272769130017E6E0 /* pngImage.png in Resources */,
86E9A896272769150017E6E0 /* jpgImage.jpg in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -383,6 +396,7 @@
9FC8F0EC229FA68500C8D58F /* gifImage.gif in Resources */,
680049382280F2B9006DD6AB /* pngImage.png in Resources */,
680049392280F2B9006DD6AB /* jpgImage.jpg in Resources */,
86E9A890272747C00017E6E0 /* webpImage.webp in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -391,6 +405,7 @@
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
86E9A89127274A360017E6E0 /* webpImage.webp in Resources */,
9FC8F0E9229FA49E00C8D58F /* gifImage.gif in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
Expand Down Expand Up @@ -499,6 +514,7 @@
files = (
334733FD266813F100DCC49E /* MetaDataUtilTests.m in Sources */,
334733FF266813FA00DCC49E /* ImagePickerTestImages.m in Sources */,
86E9A893272754860017E6E0 /* PickerSaveImageToPathOperationTests.m in Sources */,
334733FC266813EE00DCC49E /* ImageUtilTests.m in Sources */,
33473400266813FD00DCC49E /* ImagePickerPluginTests.m in Sources */,
334733FE266813F400DCC49E /* PhotoAssetUtilTests.m in Sources */,
Expand Down Expand Up @@ -565,6 +581,7 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
Comment thread
TrGiLong marked this conversation as resolved.
Outdated
INFOPLIST_FILE = RunnerTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests;
Expand All @@ -579,6 +596,7 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
Comment thread
TrGiLong marked this conversation as resolved.
Outdated
INFOPLIST_FILE = RunnerTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.plugins.RunnerTests;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// PickerSaveImageToPathOperationTests.m
// RunnerTests
//
// Created by Giang Long Tran on 25.10.21.
// Copyright © 2021 The Flutter Authors. All rights reserved.
//
Comment thread
TrGiLong marked this conversation as resolved.
Outdated

#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>

@import image_picker;

@interface PickerSaveImageToPathOperationTests : XCTestCase

@end

@implementation PickerSaveImageToPathOperationTests

- (void)testSaveWebPImage API_AVAILABLE(ios(14)); {
// Read item from bundle
NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"webpImage" withExtension:@"webp"]];

PHPickerResult *result = [self createPickerResult:itemProvider withIdentifier:UTTypeWebP.identifier];

[self testOperationWithPickerResult:result];
Comment thread
stuartmorgan-g marked this conversation as resolved.
Outdated
}

- (PHPickerResult *)createPickerResult:(NSItemProvider*)itemProvider withIdentifier:(NSString*)identifier API_AVAILABLE(ios(14)); {
PHPickerResult *result = OCMClassMock([PHPickerResult class]);

OCMStub([result itemProvider]).andReturn(itemProvider);
OCMStub([result assetIdentifier]).andReturn(identifier);

return result;
}

- (void)testOperationWithPickerResult:(PHPickerResult *)result API_AVAILABLE(ios(14)); {
XCTestExpectation *pathExpectation = [self expectationWithDescription:@"Path was created"];

FLTPHPickerSaveImageToPathOperation *operation = [[FLTPHPickerSaveImageToPathOperation alloc]
initWithResult:result
maxHeight:@100
maxWidth:@100
desiredImageQuality:@100
savedPathBlock:^(NSString *savedPath) {
if (savedPath != nil) {
[pathExpectation fulfill];
Comment thread
stuartmorgan-g marked this conversation as resolved.
Outdated
}
}];

[operation start];
[self waitForExpectations:@[pathExpectation] timeout:30];
}

@end
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#import <Foundation/Foundation.h>
#import <PhotosUI/PhotosUI.h>
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
Comment thread
TrGiLong marked this conversation as resolved.
Outdated

#import "FLTImagePickerImageUtil.h"
#import "FLTImagePickerMetaDataUtil.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,51 +82,61 @@ - (void)start {
}
if (@available(iOS 14, *)) {
[self setExecuting:YES];
[self.result.itemProvider
loadObjectOfClass:[UIImage class]
completionHandler:^(__kindof id<NSItemProviderReading> _Nullable image,
NSError *_Nullable error) {
if ([image isKindOfClass:[UIImage class]]) {
__block UIImage *localImage = image;
PHAsset *originalAsset =
[FLTImagePickerPhotoAssetUtil getAssetFromPHPickerResult:self.result];

if (self.maxWidth != (id)[NSNull null] || self.maxHeight != (id)[NSNull null]) {
localImage = [FLTImagePickerImageUtil scaledImage:localImage
maxWidth:self.maxWidth
maxHeight:self.maxHeight
isMetadataAvailable:originalAsset != nil];
}
__block NSString *savedPath;
if (!originalAsset) {
// Image picked without an original asset (e.g. User pick image without permission)
savedPath =
[FLTImagePickerPhotoAssetUtil saveImageWithPickerInfo:nil
image:localImage
imageQuality:self.desiredImageQuality];
[self completeOperationWithPath:savedPath];
} else {
[[PHImageManager defaultManager]
requestImageDataForAsset:originalAsset
options:nil
resultHandler:^(
NSData *_Nullable imageData, NSString *_Nullable dataUTI,
UIImageOrientation orientation, NSDictionary *_Nullable info) {
// maxWidth and maxHeight are used only for GIF images.
savedPath = [FLTImagePickerPhotoAssetUtil
saveImageWithOriginalImageData:imageData
image:localImage
maxWidth:self.maxWidth
maxHeight:self.maxHeight
imageQuality:self.desiredImageQuality];
[self completeOperationWithPath:savedPath];
}];
}
}

if ([self.result.itemProvider hasItemConformingToTypeIdentifier:UTTypeWebP.identifier]) {
[self.result.itemProvider loadDataRepresentationForTypeIdentifier:UTTypeWebP.identifier completionHandler:^(NSData * _Nullable data, NSError * _Nullable error) {
__block UIImage *image = [[UIImage alloc] initWithData:data];
Comment thread
TrGiLong marked this conversation as resolved.
Outdated
[self processImage:image];
}];
return;
}

[self.result.itemProvider loadObjectOfClass:[UIImage class] completionHandler:^(__kindof id<NSItemProviderReading> _Nullable image, NSError *_Nullable error) {
if ([image isKindOfClass:[UIImage class]]) {
[self processImage:image];
}
}];
} else {
[self setFinished:YES];
Comment thread
stuartmorgan-g marked this conversation as resolved.
}
}

- (void)processImage:(UIImage *)image API_AVAILABLE(ios(14)); {
Comment thread
TrGiLong marked this conversation as resolved.
Outdated
__block UIImage *localImage = image;
Comment thread
TrGiLong marked this conversation as resolved.
Outdated
PHAsset *originalAsset =
[FLTImagePickerPhotoAssetUtil getAssetFromPHPickerResult:self.result];

if (self.maxWidth != (id)[NSNull null] || self.maxHeight != (id)[NSNull null]) {
localImage = [FLTImagePickerImageUtil scaledImage:localImage
maxWidth:self.maxWidth
maxHeight:self.maxHeight
isMetadataAvailable:originalAsset != nil];
}
__block NSString *savedPath;
Comment thread
TrGiLong marked this conversation as resolved.
Outdated
if (!originalAsset) {
// Image picked without an original asset (e.g. User pick image without permission)
savedPath =
[FLTImagePickerPhotoAssetUtil saveImageWithPickerInfo:nil
image:localImage
imageQuality:self.desiredImageQuality];
[self completeOperationWithPath:savedPath];
} else {
[[PHImageManager defaultManager]
requestImageDataForAsset:originalAsset
options:nil
resultHandler:^(
NSData *_Nullable imageData, NSString *_Nullable dataUTI,
UIImageOrientation orientation, NSDictionary *_Nullable info) {
// maxWidth and maxHeight are used only for GIF images.
savedPath = [FLTImagePickerPhotoAssetUtil
saveImageWithOriginalImageData:imageData
image:localImage
maxWidth:self.maxWidth
maxHeight:self.maxHeight
imageQuality:self.desiredImageQuality];
[self completeOperationWithPath:savedPath];
}];
}
}

@end
2 changes: 1 addition & 1 deletion packages/image_picker/image_picker/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Flutter plugin for selecting images from the Android and iOS image
library, and taking new pictures with the camera.
repository: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
version: 0.8.4+3
version: 0.8.4+4

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down