Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit f4c3207

Browse files
committed
[image_picker] add original image name to exif header
1 parent 54e748c commit f4c3207

6 files changed

Lines changed: 98 additions & 5 deletions

File tree

packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ExifDataCopier.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
import java.util.List;
1111

1212
class ExifDataCopier {
13+
static void setImageDescription(String filePathOri, String imageDescription) {
14+
try {
15+
ExifInterface exif = new ExifInterface(filePathOri);
16+
exif.setAttribute("ImageDescription", imageDescription);
17+
exif.saveAttributes();
18+
} catch (Exception ex) {
19+
Log.e("ExifDataCopier", "Error setImageDescription: " + ex);
20+
}
21+
}
22+
1323
void copyExif(String filePathOri, String filePathDest) {
1424
try {
1525
ExifInterface oldExif = new ExifInterface(filePathOri);
@@ -35,7 +45,8 @@ void copyExif(String filePathOri, String filePathDest) {
3545
"GPSLongitudeRef",
3646
"Make",
3747
"Model",
38-
"Orientation");
48+
"Orientation",
49+
"ImageDescription");
3950
for (String attribute : attributes) {
4051
setIfNotNull(oldExif, newExif, attribute);
4152
}

packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525

2626
import android.content.ContentResolver;
2727
import android.content.Context;
28+
import android.database.Cursor;
2829
import android.net.Uri;
30+
import android.provider.OpenableColumns;
2931
import android.webkit.MimeTypeMap;
3032
import java.io.File;
3133
import java.io.FileOutputStream;
@@ -42,13 +44,18 @@ String getPathFromUri(final Context context, final Uri uri) {
4244
boolean success = false;
4345
try {
4446
String extension = getImageExtension(context, uri);
47+
String originFileName = getImageOriginalName(context, uri);
4548
inputStream = context.getContentResolver().openInputStream(uri);
4649
file = File.createTempFile("image_picker", extension, context.getCacheDir());
4750
file.deleteOnExit();
4851
outputStream = new FileOutputStream(file);
4952
if (inputStream != null) {
5053
copy(inputStream, outputStream);
5154
success = true;
55+
56+
if(originFileName != null) {
57+
ExifDataCopier.setImageDescription(file.getPath(), originFileName);
58+
}
5259
}
5360
} catch (IOException ignored) {
5461
} finally {
@@ -94,6 +101,39 @@ private static String getImageExtension(Context context, Uri uriImage) {
94101
return "." + extension;
95102
}
96103

104+
/** @return original file name. */
105+
private static String getImageOriginalName(Context context, Uri uriImage) {
106+
String result = null;
107+
Cursor cursor = null;
108+
109+
try {
110+
if (uriImage.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
111+
cursor = context.getContentResolver().query(uriImage, null, null, null, null);
112+
113+
if (cursor != null && cursor.moveToFirst()) {
114+
int idx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
115+
result = cursor.getString(idx);
116+
}
117+
118+
}
119+
} catch (Exception e) {
120+
result = null;
121+
} finally {
122+
cursor.close();
123+
}
124+
125+
if (result == null || result.isEmpty()) {
126+
//default file name
127+
result = uriImage.getPath();
128+
int cut = result.lastIndexOf('/');
129+
if (cut != -1) {
130+
result = result.substring(cut + 1);
131+
}
132+
}
133+
134+
return result;
135+
}
136+
97137
private static void copy(InputStream in, OutputStream out) throws IOException {
98138
final byte[] buffer = new byte[4 * 1024];
99139
int bytesRead;

packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerPhotoAssetUtil.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ NS_ASSUME_NONNULL_BEGIN
2424
maxHeight:(nullable NSNumber *)maxHeight
2525
imageQuality:(nullable NSNumber *)imageQuality;
2626

27+
+ (NSString *)saveImageWithOriginalImageData:(NSData *)originalImageData
28+
image:(UIImage *)image
29+
maxWidth:(nullable NSNumber *)maxWidth
30+
maxHeight:(nullable NSNumber *)maxHeight
31+
imageQuality:(nullable NSNumber *)imageQuality
32+
originalFileName:(nullable NSString *)originalFileName;
33+
2734
// Save image with correct meta data and extention copied from image picker result info.
2835
+ (NSString *)saveImageWithPickerInfo:(nullable NSDictionary *)info
2936
image:(UIImage *)image

packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerPhotoAssetUtil.m

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,52 @@ + (PHAsset *)getAssetFromPHPickerResult:(PHPickerResult *)result API_AVAILABLE(i
3232
return fetchResult.firstObject;
3333
}
3434

35+
+ (NSString *)saveImageWithOriginalImageData:(NSData *)originalImageData
36+
image:(UIImage *)image
37+
maxWidth:(nullable NSNumber *)maxWidth
38+
maxHeight:(nullable NSNumber *)maxHeight
39+
imageQuality:(nullable NSNumber *)imageQuality {
40+
return [self saveImageWithOriginalImageData:originalImageData image:image maxWidth:maxWidth maxHeight:maxHeight imageQuality:imageQuality originalFileName:nil];
41+
}
42+
3543
+ (NSString *)saveImageWithOriginalImageData:(NSData *)originalImageData
3644
image:(UIImage *)image
3745
maxWidth:(NSNumber *)maxWidth
3846
maxHeight:(NSNumber *)maxHeight
39-
imageQuality:(NSNumber *)imageQuality {
47+
imageQuality:(NSNumber *)imageQuality
48+
originalFileName:(NSString *)originalFileName {
4049
NSString *suffix = kFLTImagePickerDefaultSuffix;
4150
FLTImagePickerMIMEType type = kFLTImagePickerMIMETypeDefault;
42-
NSDictionary *metaData = nil;
51+
NSMutableDictionary *metaData = [NSMutableDictionary dictionary];
52+
4353
// Getting the image type from the original image data if necessary.
4454
if (originalImageData) {
4555
type = [FLTImagePickerMetaDataUtil getImageMIMETypeFromImageData:originalImageData];
4656
suffix =
4757
[FLTImagePickerMetaDataUtil imageTypeSuffixFromType:type] ?: kFLTImagePickerDefaultSuffix;
48-
metaData = [FLTImagePickerMetaDataUtil getMetaDataFromImageData:originalImageData];
58+
NSDictionary *imageMetaData = [FLTImagePickerMetaDataUtil getMetaDataFromImageData:originalImageData];
59+
if(imageMetaData) {
60+
[metaData addEntriesFromDictionary:imageMetaData];
61+
}
4962
}
63+
5064
if (type == FLTImagePickerMIMETypeGIF) {
5165
GIFInfo *gifInfo = [FLTImagePickerImageUtil scaledGIFImage:originalImageData
5266
maxWidth:maxWidth
5367
maxHeight:maxHeight];
5468

5569
return [self saveImageWithMetaData:metaData gifInfo:gifInfo suffix:suffix];
5670
} else {
71+
if(originalFileName) {
72+
NSMutableDictionary *tiff = [metaData[@"{TIFF}"] mutableCopy];
73+
if(!tiff) {
74+
tiff = [NSMutableDictionary dictionary];
75+
}
76+
77+
tiff[@"ImageDescription"] = originalFileName;
78+
metaData[@"{TIFF}"] = tiff;
79+
}
80+
5781
return [self saveImageWithMetaData:metaData
5882
image:image
5983
suffix:suffix

packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerPlugin.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ - (void)launchPHPickerWithContext:(nonnull FLTImagePickerMethodCallContext *)con
113113
[[PHPickerConfiguration alloc] initWithPhotoLibrary:PHPhotoLibrary.sharedPhotoLibrary];
114114
config.selectionLimit = context.maxImageCount;
115115
config.filter = [PHPickerFilter imagesFilter];
116+
117+
if (@available(iOS 15, *)) {
118+
config.selection = PHPickerConfigurationSelectionOrdered;
119+
}
116120

117121
_pickerViewController = [[PHPickerViewController alloc] initWithConfiguration:config];
118122
_pickerViewController.delegate = self;

packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,16 @@ - (void)start {
117117
*/
118118
- (void)processImage:(UIImage *)localImage API_AVAILABLE(ios(14)) {
119119
PHAsset *originalAsset;
120+
NSString *originalFileName;
121+
NSMutableDictionary *metaData = [NSMutableDictionary dictionary];
120122
// Only if requested, fetch the full "PHAsset" metadata, which requires "Photo Library Usage"
121123
// permissions.
122124
if (self.requestFullMetadata) {
123125
originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromPHPickerResult:self.result];
126+
NSArray *resources = [PHAssetResource assetResourcesForAsset:originalAsset];
127+
if(resources.count > 0) {
128+
originalFileName = ((PHAssetResource*)resources[0]).originalFilename;
129+
}
124130
}
125131

126132
if (self.maxWidth != nil || self.maxHeight != nil) {
@@ -138,7 +144,8 @@ - (void)processImage:(UIImage *)localImage API_AVAILABLE(ios(14)) {
138144
image:localImage
139145
maxWidth:self.maxWidth
140146
maxHeight:self.maxHeight
141-
imageQuality:self.desiredImageQuality];
147+
imageQuality:self.desiredImageQuality
148+
originalFileName:originalFileName];
142149
[self completeOperationWithPath:savedPath];
143150
};
144151
if (@available(iOS 13.0, *)) {

0 commit comments

Comments
 (0)