FLTImagePickerPhotoAssetUtil.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 2019 The Flutter Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #import "FLTImagePickerPhotoAssetUtil.h"
  5. #import "FLTImagePickerImageUtil.h"
  6. #import "FLTImagePickerMetaDataUtil.h"
  7. #import <MobileCoreServices/MobileCoreServices.h>
  8. @implementation FLTImagePickerPhotoAssetUtil
  9. + (PHAsset *)getAssetFromImagePickerInfo:(NSDictionary *)info {
  10. if (@available(iOS 11, *)) {
  11. return [info objectForKey:UIImagePickerControllerPHAsset];
  12. }
  13. NSURL *referenceURL = [info objectForKey:UIImagePickerControllerReferenceURL];
  14. if (!referenceURL) {
  15. return nil;
  16. }
  17. PHFetchResult<PHAsset *> *result = [PHAsset fetchAssetsWithALAssetURLs:@[ referenceURL ]
  18. options:nil];
  19. return result.firstObject;
  20. }
  21. + (NSString *)saveImageWithOriginalImageData:(NSData *)originalImageData
  22. image:(UIImage *)image
  23. maxWidth:(NSNumber *)maxWidth
  24. maxHeight:(NSNumber *)maxHeight
  25. imageQuality:(NSNumber *)imageQuality {
  26. NSString *suffix = kFLTImagePickerDefaultSuffix;
  27. FLTImagePickerMIMEType type = kFLTImagePickerMIMETypeDefault;
  28. NSDictionary *metaData = nil;
  29. // Getting the image type from the original image data if necessary.
  30. if (originalImageData) {
  31. type = [FLTImagePickerMetaDataUtil getImageMIMETypeFromImageData:originalImageData];
  32. suffix =
  33. [FLTImagePickerMetaDataUtil imageTypeSuffixFromType:type] ?: kFLTImagePickerDefaultSuffix;
  34. metaData = [FLTImagePickerMetaDataUtil getMetaDataFromImageData:originalImageData];
  35. }
  36. if (type == FLTImagePickerMIMETypeGIF) {
  37. GIFInfo *gifInfo = [FLTImagePickerImageUtil scaledGIFImage:originalImageData
  38. maxWidth:maxWidth
  39. maxHeight:maxHeight];
  40. return [self saveImageWithMetaData:metaData gifInfo:gifInfo suffix:suffix];
  41. } else {
  42. return [self saveImageWithMetaData:metaData
  43. image:image
  44. suffix:suffix
  45. type:type
  46. imageQuality:imageQuality];
  47. }
  48. }
  49. + (NSString *)saveImageWithPickerInfo:(nullable NSDictionary *)info
  50. image:(UIImage *)image
  51. imageQuality:(NSNumber *)imageQuality {
  52. NSDictionary *metaData = info[UIImagePickerControllerMediaMetadata];
  53. return [self saveImageWithMetaData:metaData
  54. image:image
  55. suffix:kFLTImagePickerDefaultSuffix
  56. type:kFLTImagePickerMIMETypeDefault
  57. imageQuality:imageQuality];
  58. }
  59. + (NSString *)saveImageWithMetaData:(NSDictionary *)metaData
  60. gifInfo:(GIFInfo *)gifInfo
  61. suffix:(NSString *)suffix {
  62. NSString *path = [self temporaryFilePath:suffix];
  63. return [self saveImageWithMetaData:metaData gifInfo:gifInfo path:path];
  64. }
  65. + (NSString *)saveImageWithMetaData:(NSDictionary *)metaData
  66. image:(UIImage *)image
  67. suffix:(NSString *)suffix
  68. type:(FLTImagePickerMIMEType)type
  69. imageQuality:(NSNumber *)imageQuality {
  70. NSData *data = [FLTImagePickerMetaDataUtil convertImage:image
  71. usingType:type
  72. quality:imageQuality];
  73. if (metaData) {
  74. data = [FLTImagePickerMetaDataUtil updateMetaData:metaData toImage:data];
  75. }
  76. return [self createFile:data suffix:suffix];
  77. }
  78. + (NSString *)saveImageWithMetaData:(NSDictionary *)metaData
  79. gifInfo:(GIFInfo *)gifInfo
  80. path:(NSString *)path {
  81. CGImageDestinationRef destination = CGImageDestinationCreateWithURL(
  82. (CFURLRef)[NSURL fileURLWithPath:path], kUTTypeGIF, gifInfo.images.count, NULL);
  83. NSDictionary *frameProperties = [NSDictionary
  84. dictionaryWithObject:[NSDictionary
  85. dictionaryWithObject:[NSNumber numberWithFloat:gifInfo.interval]
  86. forKey:(NSString *)kCGImagePropertyGIFDelayTime]
  87. forKey:(NSString *)kCGImagePropertyGIFDictionary];
  88. NSMutableDictionary *gifMetaProperties = [NSMutableDictionary dictionaryWithDictionary:metaData];
  89. NSMutableDictionary *gifProperties =
  90. (NSMutableDictionary *)gifMetaProperties[(NSString *)kCGImagePropertyGIFDictionary];
  91. if (gifMetaProperties == nil) {
  92. gifProperties = [NSMutableDictionary dictionary];
  93. }
  94. gifProperties[(NSString *)kCGImagePropertyGIFLoopCount] = [NSNumber numberWithFloat:0];
  95. CGImageDestinationSetProperties(destination, (CFDictionaryRef)gifMetaProperties);
  96. for (NSInteger index = 0; index < gifInfo.images.count; index++) {
  97. UIImage *image = (UIImage *)[gifInfo.images objectAtIndex:index];
  98. CGImageDestinationAddImage(destination, image.CGImage, (CFDictionaryRef)frameProperties);
  99. }
  100. CGImageDestinationFinalize(destination);
  101. CFRelease(destination);
  102. return path;
  103. }
  104. + (NSString *)temporaryFilePath:(NSString *)suffix {
  105. NSString *fileExtension = [@"image_picker_%@" stringByAppendingString:suffix];
  106. NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString];
  107. NSString *tmpFile = [NSString stringWithFormat:fileExtension, guid];
  108. NSString *tmpDirectory = NSTemporaryDirectory();
  109. NSString *tmpPath = [tmpDirectory stringByAppendingPathComponent:tmpFile];
  110. return tmpPath;
  111. }
  112. + (NSString *)createFile:(NSData *)data suffix:(NSString *)suffix {
  113. NSString *tmpPath = [self temporaryFilePath:suffix];
  114. if ([[NSFileManager defaultManager] createFileAtPath:tmpPath contents:data attributes:nil]) {
  115. return tmpPath;
  116. } else {
  117. nil;
  118. }
  119. return tmpPath;
  120. }
  121. @end