mirror of
https://github.com/apache/cordova-plugin-camera.git
synced 2026-02-25 00:00:06 +08:00
Compare commits
2 Commits
master
...
pr-resultf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
277e21336f | ||
|
|
64b28461c6 |
@@ -421,17 +421,37 @@ static NSString* MIME_JPEG = @"image/jpeg";
|
||||
}
|
||||
|
||||
/**
|
||||
Prepares the image and metadata obtained from PHPickerImageViewController which will be processed in
|
||||
resultForImage:. After that CDVPluginResult is returned.
|
||||
Processes an image obtained from PHPickerViewController according to specified pictureOptions,
|
||||
after it returns the CDVPluginResult.
|
||||
The processing of the image is similar what retrieveImage: and processImage: is doing for UIImagePickerController.
|
||||
*/
|
||||
- (void)processPHPickerImage:(UIImage*)image
|
||||
metadata:(NSDictionary*)metadata
|
||||
callbackId:(NSString*)callbackId
|
||||
options:(CDVPictureOptions*)options API_AVAILABLE(ios(14))
|
||||
{
|
||||
// To shrink the file size, only selected meta data like EXIF, TIFF, and GPS is used,
|
||||
// which will be stored in self.metadata, which is set to the image in resultForImage:
|
||||
// This code replicates the logic from processImage: for the UIImagePickerController
|
||||
// Process image according to options
|
||||
// The same is done in retrieveImage:
|
||||
UIImage *processedImage = image;
|
||||
|
||||
if (options.correctOrientation) {
|
||||
processedImage = [processedImage imageCorrectedForCaptureOrientation];
|
||||
}
|
||||
|
||||
// Scale with optional cropping
|
||||
if ((options.targetSize.width > 0) && (options.targetSize.height > 0)) {
|
||||
// Scale and crop to target size
|
||||
if (options.cropToSize) {
|
||||
processedImage = [processedImage imageByScalingAndCroppingForSize:options.targetSize];
|
||||
|
||||
// Scale with no cropping
|
||||
} else {
|
||||
processedImage = [processedImage imageByScalingNotCroppingForSize:options.targetSize];
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare self.metadata, which replicates the logic from processImage: for the UIImagePickerController
|
||||
// self.metadata which will be set to the image in resultForImage:
|
||||
if (metadata.count > 0) {
|
||||
self.metadata = [NSMutableDictionary dictionary];
|
||||
|
||||
@@ -451,19 +471,18 @@ static NSString* MIME_JPEG = @"image/jpeg";
|
||||
}
|
||||
}
|
||||
|
||||
// Mimic the info dictionary which would be created by UIImagePickerController
|
||||
// Add image, which will be used in retrieveImage: to get the image and do processing
|
||||
NSMutableDictionary *info = [@{UIImagePickerControllerOriginalImage : image} mutableCopy];
|
||||
// Return Cordova result to WebView
|
||||
// Needed weakSelf for completion block
|
||||
__weak CDVCamera* weakSelf = self;
|
||||
|
||||
// Create info dictionary similar to UIImagePickerController
|
||||
// Will be used in retrieveImage: to get the image and do processing like here was done
|
||||
NSMutableDictionary *info = [@{ UIImagePickerControllerOriginalImage : processedImage } mutableCopy];
|
||||
|
||||
// Add metadata if available
|
||||
if (metadata.count > 0) {
|
||||
// This is not used anywhere and can be removed
|
||||
info[UIImagePickerControllerMediaMetadata] = metadata;
|
||||
}
|
||||
|
||||
// Return Cordova result to WebView
|
||||
// Needed weakSelf for completion block
|
||||
__weak CDVCamera* weakSelf = self;
|
||||
|
||||
// Process and return result
|
||||
[self resultForImage:options info:info completion:^(CDVPluginResult* pluginResult) {
|
||||
@@ -695,50 +714,44 @@ static NSString* MIME_JPEG = @"image/jpeg";
|
||||
|
||||
- (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)options
|
||||
{
|
||||
UIImage* pickedImage = nil;
|
||||
|
||||
// Get the picked image from info dictionary
|
||||
// get the image
|
||||
UIImage* image = nil;
|
||||
if (options.allowsEditing && [info objectForKey:UIImagePickerControllerEditedImage]) {
|
||||
pickedImage = [info objectForKey:UIImagePickerControllerEditedImage];
|
||||
image = [info objectForKey:UIImagePickerControllerEditedImage];
|
||||
} else {
|
||||
pickedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||
image = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||
}
|
||||
|
||||
// Process image according to options
|
||||
UIImage *processedImage = pickedImage;
|
||||
|
||||
if (options.correctOrientation) {
|
||||
processedImage = [processedImage imageCorrectedForCaptureOrientation];
|
||||
image = [image imageCorrectedForCaptureOrientation];
|
||||
}
|
||||
|
||||
// Scale with optional cropping
|
||||
if (options.targetSize.width > 0 && options.targetSize.height > 0) {
|
||||
// Scale and crop to target size
|
||||
if (options.cropToSize) {
|
||||
processedImage = [processedImage imageByScalingAndCroppingForSize:options.targetSize];
|
||||
|
||||
// Scale with no cropping
|
||||
UIImage* scaledImage = nil;
|
||||
|
||||
if ((options.targetSize.width > 0) && (options.targetSize.height > 0)) {
|
||||
// if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping
|
||||
if (options.cropToSize) {
|
||||
scaledImage = [image imageByScalingAndCroppingForSize:options.targetSize];
|
||||
} else {
|
||||
processedImage = [processedImage imageByScalingNotCroppingForSize:options.targetSize];
|
||||
scaledImage = [image imageByScalingNotCroppingForSize:options.targetSize];
|
||||
}
|
||||
}
|
||||
|
||||
return processedImage;
|
||||
return (scaledImage == nil ? image : scaledImage);
|
||||
}
|
||||
|
||||
- (void)resultForImage:(CDVPictureOptions*)options
|
||||
- (void)resultForImage:(CDVPictureOptions*)pictureOptions
|
||||
info:(NSDictionary*)info
|
||||
completion:(void (^)(CDVPluginResult* res))completion
|
||||
{
|
||||
CDVPluginResult* result = nil;
|
||||
BOOL saveToPhotoAlbum = options.saveToPhotoAlbum;
|
||||
UIImage* image = nil;
|
||||
|
||||
switch (options.destinationType) {
|
||||
switch (pictureOptions.destinationType) {
|
||||
case DestinationTypeDataUrl:
|
||||
{
|
||||
image = [self retrieveImage:info options:options];
|
||||
NSString* data = [self processImageAsDataUri:image info:info options:options];
|
||||
image = [self retrieveImage:info options:pictureOptions];
|
||||
NSString* data = [self processImageAsDataUri:image info:info options:pictureOptions];
|
||||
if (data) {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: data];
|
||||
}
|
||||
@@ -746,48 +759,57 @@ static NSString* MIME_JPEG = @"image/jpeg";
|
||||
break;
|
||||
default: // DestinationTypeFileUri
|
||||
{
|
||||
image = [self retrieveImage:info options:options];
|
||||
NSData* data = [self processImage:image info:info options:options];
|
||||
image = [self retrieveImage:info options:pictureOptions];
|
||||
NSData* imageData = [self processImage:image info:info options:pictureOptions];
|
||||
|
||||
if (data) {
|
||||
if (self.cdvUIImagePickerController.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) {
|
||||
NSMutableData *imageDataWithExif = [NSMutableData data];
|
||||
if (imageData) {
|
||||
if (pictureOptions.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) {
|
||||
|
||||
NSData *imageDataToWrite = imageData;
|
||||
|
||||
// Copy custom choosen meta data stored in self.metadata to the image
|
||||
if (self.metadata) {
|
||||
CGImageSourceRef sourceImage = CGImageSourceCreateWithData((__bridge CFDataRef)self.data, NULL);
|
||||
NSMutableData *imageDataWithCustomMetaData = [NSMutableData data];
|
||||
|
||||
// Prepare source image
|
||||
CGImageSourceRef sourceImage = CGImageSourceCreateWithData((__bridge CFDataRef)imageDataToWrite, NULL);
|
||||
CFStringRef sourceType = CGImageSourceGetType(sourceImage);
|
||||
|
||||
CGImageDestinationRef destinationImage = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageDataWithExif, sourceType, 1, NULL);
|
||||
|
||||
// Prepare dest image
|
||||
CGImageDestinationRef destinationImage = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageDataWithCustomMetaData, sourceType, 1, NULL);
|
||||
|
||||
// Copy source to dest with self.metadata
|
||||
CGImageDestinationAddImageFromSource(destinationImage, sourceImage, 0, (__bridge CFDictionaryRef)self.metadata);
|
||||
CGImageDestinationFinalize(destinationImage);
|
||||
|
||||
CFRelease(sourceImage);
|
||||
CFRelease(destinationImage);
|
||||
} else {
|
||||
imageDataWithExif = [self.data mutableCopy];
|
||||
|
||||
imageDataToWrite = imageDataWithCustomMetaData;
|
||||
}
|
||||
|
||||
NSString* tempFilePath = [self tempFilePathForExtension:pictureOptions.encodingType == EncodingTypePNG ? @"png":@"jpg"];
|
||||
NSError* err = nil;
|
||||
NSString* extension = self.cdvUIImagePickerController.pictureOptions.encodingType == EncodingTypePNG ? @"png":@"jpg";
|
||||
NSString* filePath = [self tempFilePathForExtension:extension];
|
||||
|
||||
// save file
|
||||
if (![imageDataWithExif writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
||||
|
||||
// Write image to temp path
|
||||
if ([imageDataToWrite writeToFile:tempFilePath options:NSAtomicWrite error:&err]) {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
||||
messageAsString:[[NSURL fileURLWithPath:tempFilePath] absoluteString]];
|
||||
|
||||
// Write was not successful
|
||||
} else {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION
|
||||
messageAsString:[err localizedDescription]];
|
||||
}
|
||||
else {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
||||
messageAsString:[[NSURL fileURLWithPath:filePath] absoluteString]];
|
||||
}
|
||||
|
||||
} else if (self.cdvUIImagePickerController.sourceType != UIImagePickerControllerSourceTypeCamera || !options.usesGeolocation) {
|
||||
} else if (pictureOptions.sourceType != UIImagePickerControllerSourceTypeCamera || !pictureOptions.usesGeolocation) {
|
||||
// No need to save file if usesGeolocation is true since it will be saved after the location is tracked
|
||||
NSString* extension = options.encodingType == EncodingTypePNG? @"png" : @"jpg";
|
||||
NSString* extension = pictureOptions.encodingType == EncodingTypePNG? @"png" : @"jpg";
|
||||
NSString* filePath = [self tempFilePathForExtension:extension];
|
||||
NSError* err = nil;
|
||||
|
||||
// save file
|
||||
if (![data writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
||||
if (![imageData writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
||||
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION
|
||||
messageAsString:[err localizedDescription]];
|
||||
} else {
|
||||
@@ -801,7 +823,8 @@ static NSString* MIME_JPEG = @"image/jpeg";
|
||||
break;
|
||||
};
|
||||
|
||||
if (saveToPhotoAlbum && image) {
|
||||
// Save the image to the photo album after capture
|
||||
if (pictureOptions.saveToPhotoAlbum && image) {
|
||||
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user