Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
15 changes: 2 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,19 +276,14 @@ Optional parameters to customize the camera settings.

### Camera.DestinationType : <code>enum</code>
Defines the output format of `Camera.getPicture` call.
_Note:_ On iOS passing `DestinationType.NATIVE_URI` along with
`PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM` will
disable any image modifications (resize, quality change, cropping, etc.) due
to implementation specific.

**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| DATA_URL | <code>number</code> | <code>0</code> | Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI or NATIVE_URI if possible |
| DATA_URL | <code>number</code> | <code>0</code> | Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI if possible |
| FILE_URI | <code>number</code> | <code>1</code> | Return file uri (content://media/external/images/media/2 for Android) |
| NATIVE_URI | <code>number</code> | <code>2</code> | Return native uri (eg. asset-library://... for iOS) |

<a name="module_Camera.EncodingType"></a>

Expand Down Expand Up @@ -317,9 +312,6 @@ to implementation specific.

### Camera.PictureSourceType : <code>enum</code>
Defines the output format of `Camera.getPicture` call.
_Note:_ On iOS passing `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM`
along with `DestinationType.NATIVE_URI` will disable any image modifications (resize, quality
change, cropping, etc.) due to implementation specific.

**Kind**: static enum property of <code>[Camera](#module_Camera)</code>
**Properties**
Expand Down Expand Up @@ -435,7 +427,7 @@ Take a photo and retrieve it as a Base64-encoded image:
* Warning: Using DATA_URL is not recommended! The DATA_URL destination
* type is very memory intensive, even with a low quality setting. Using it
* can result in out of memory errors and application crashes. Use FILE_URI
* or NATIVE_URI instead.
* instead.
*/
navigator.camera.getPicture(onSuccess, onFail, { quality: 25,
destinationType: Camera.DestinationType.DATA_URL
Expand Down Expand Up @@ -508,9 +500,6 @@ More information about Windows Phone 8.1 picker APIs is here: [How to continue y

- When using `destinationType.FILE_URI`, photos are saved in the application's temporary directory. The contents of the application's temporary directory is deleted when the application ends.

- When using `destinationType.NATIVE_URI` and `sourceType.CAMERA`, photos are saved in the saved photo album regardless on the value of `saveToPhotoAlbum` parameter.

- When using `destinationType.NATIVE_URI` and `sourceType.PHOTOLIBRARY` or `sourceType.SAVEDPHOTOALBUM`, all editing options are ignored and link is returned to original picture.

[android_lifecycle]: http://cordova.apache.org/docs/en/dev/guide/platforms/android/lifecycle.html

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions src/android/CameraLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect

private static final int DATA_URL = 0; // Return base64 encoded string
private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android)
private static final int NATIVE_URI = 2; // On Android, this is the same as FILE_URI

private static final int PHOTOLIBRARY = 0; // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
private static final int CAMERA = 1; // Take picture from camera
Expand Down Expand Up @@ -532,7 +531,7 @@ private void processResultFromCamera(int destType, Intent intent) throws IOExcep
}

// If sending filename back
else if (destType == FILE_URI || destType == NATIVE_URI) {
else if (destType == FILE_URI) {
// If all this is true we shouldn't compress the image.
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 &&
!this.correctOrientation) {
Expand Down Expand Up @@ -703,7 +702,7 @@ private void processResultFromGallery(int destType, Intent intent) {
// This is a special case to just return the path as no scaling,
// rotating, nor compressing needs to be done
if (this.targetHeight == -1 && this.targetWidth == -1 &&
(destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation &&
destType == FILE_URI && !this.correctOrientation &&
mimeType != null && mimeType.equalsIgnoreCase(getMimetypeForFormat(encodingType)))
{
this.callbackContext.success(finalLocation);
Expand All @@ -726,7 +725,7 @@ private void processResultFromGallery(int destType, Intent intent) {
}

// If sending filename back
else if (destType == FILE_URI || destType == NATIVE_URI) {
else if (destType == FILE_URI) {
// Did we modify the image?
if ( (this.targetHeight > 0 && this.targetWidth > 0) ||
(this.correctOrientation && this.orientationCorrected) ||
Expand Down
3 changes: 1 addition & 2 deletions src/ios/CDVCamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@

enum CDVDestinationType {
DestinationTypeDataUrl = 0,
DestinationTypeFileUri,
DestinationTypeNativeUri
DestinationTypeFileUri
};
typedef NSUInteger CDVDestinationType;

Expand Down
67 changes: 16 additions & 51 deletions src/ios/CDVCamera.m
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ - (void)takePicture:(CDVInvokedUrlCommand*)command
[weakSelf sendNoPermissionResult:command.callbackId];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Settings", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
[weakSelf sendNoPermissionResult:command.callbackId];
}]];
[weakSelf.viewController presentViewController:alertController animated:YES completion:nil];
Expand Down Expand Up @@ -440,33 +440,16 @@ - (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info comp
UIImage* image = nil;

switch (options.destinationType) {
case DestinationTypeNativeUri:
case DestinationTypeDataUrl:
{
NSURL* url = [info objectForKey:UIImagePickerControllerReferenceURL];
saveToPhotoAlbum = NO;
// If, for example, we use sourceType = Camera, URL might be nil because image is stored in memory.
// In this case we must save image to device before obtaining an URI.
if (url == nil) {
image = [self retrieveImage:info options:options];
ALAssetsLibrary* library = [ALAssetsLibrary new];
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:^(NSURL *assetURL, NSError *error) {
CDVPluginResult* resultToReturn = nil;
if (error) {
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
} else {
NSString* nativeUri = [[self urlTransformer:assetURL] absoluteString];
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
}
completion(resultToReturn);
}];
return;
} else {
NSString* nativeUri = [[self urlTransformer:url] absoluteString];
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
image = [self retrieveImage:info options:options];
NSData* data = [self processImage:image info:info options:options];
if (data) {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
}
}
break;
case DestinationTypeFileUri:
default: // DestinationTypeFileUri
{
image = [self retrieveImage:info options:options];
NSData* data = [self processImage:image info:info options:options];
Expand All @@ -485,22 +468,10 @@ - (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info comp
}
}
break;
case DestinationTypeDataUrl:
{
image = [self retrieveImage:info options:options];
NSData* data = [self processImage:image info:info options:options];
if (data) {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
}
}
break;
default:
break;
};

if (saveToPhotoAlbum && image) {
ALAssetsLibrary* library = [ALAssetsLibrary new];
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}

completion(result);
Expand Down Expand Up @@ -576,10 +547,8 @@ - (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker

dispatch_block_t invoke = ^ (void) {
CDVPluginResult* result;
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera && [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != ALAuthorizationStatusAuthorized) {
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera && [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != AVAuthorizationStatusAuthorized) {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to camera"];
} else if (picker.sourceType != UIImagePickerControllerSourceTypeCamera && ! IsAtLeastiOSVersion(@"11.0") && [ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusAuthorized) {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to assets"];
} else {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No Image Selected"];
}
Expand Down Expand Up @@ -694,7 +663,12 @@ - (void)imagePickerControllerReturnImageResult
}

switch (options.destinationType) {
case DestinationTypeFileUri:
case DestinationTypeDataUrl:
{
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(self.data)];
}
break;
default: // DestinationTypeFileUri
{
NSError* err = nil;
NSString* extension = self.pickerController.pictureOptions.encodingType == EncodingTypePNG ? @"png":@"jpg";
Expand All @@ -709,14 +683,6 @@ - (void)imagePickerControllerReturnImageResult
}
}
break;
case DestinationTypeDataUrl:
{
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(self.data)];
}
break;
case DestinationTypeNativeUri:
default:
break;
};

if (result) {
Expand All @@ -729,8 +695,7 @@ - (void)imagePickerControllerReturnImageResult
self.metadata = nil;

if (options.saveToPhotoAlbum) {
ALAssetsLibrary *library = [ALAssetsLibrary new];
[library writeImageDataToSavedPhotosAlbum:self.data metadata:self.metadata completionBlock:nil];
UIImageWriteToSavedPhotosAlbum([[UIImage alloc] initWithData:self.data], nil, nil, nil);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/osx/CDVCamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@

enum CDVDestinationType {
DestinationTypeDataUrl = 0,
DestinationTypeFileUri,
DestinationTypeNativeUri
DestinationTypeFileUri
};
typedef NSUInteger CDVDestinationType;

Expand Down
2 changes: 1 addition & 1 deletion src/osx/CDVCamera.m
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ - (void)takePictureFromFile:(CDVInvokedUrlCommand *)command withOptions:(CDVPict

/*!
Returns to JavaScript a URI.
Called when Camera.DestinationType.FILE_URI or Camera.DestinationType.NATIVE_URI.
Called when Camera.DestinationType.FILE_URI.
*/
- (void)returnUri:(NSString *)path command:(CDVInvokedUrlCommand *)command options:(CDVPictureOptions *)pictureOptions {
NSString *protocol = (pictureOptions.destinationType == DestinationTypeFileUri) ? @"file://" : @"";
Expand Down
18 changes: 5 additions & 13 deletions src/windows/CameraProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,13 @@ function takePictureFromFileWP (successCallback, errorCallback, args) {
webUIApp.removeEventListener('activated', filePickerActivationHandler);
return;
}
if (destinationType === Camera.DestinationType.FILE_URI || destinationType === Camera.DestinationType.NATIVE_URI) {
if (destinationType === Camera.DestinationType.FILE_URI) {
if (targetHeight > 0 && targetWidth > 0) {
resizeImage(successCallback, errorCallback, file, targetWidth, targetHeight, encodingType);
} else {
var storageFolder = getAppData().localFolder;
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).done(function (storageFile) {
if (destinationType === Camera.DestinationType.NATIVE_URI) {
successCallback('ms-appdata:///local/' + storageFile.name);
} else {
successCallback(URL.createObjectURL(storageFile));
}
successCallback(URL.createObjectURL(storageFile));
}, function () {
errorCallback("Can't access localStorage folder.");
});
Expand Down Expand Up @@ -259,17 +255,13 @@ function takePictureFromFileWindows (successCallback, errorCallback, args) {
errorCallback("User didn't choose a file.");
return;
}
if (destinationType === Camera.DestinationType.FILE_URI || destinationType === Camera.DestinationType.NATIVE_URI) {
if (destinationType === Camera.DestinationType.FILE_URI) {
if (targetHeight > 0 && targetWidth > 0) {
resizeImage(successCallback, errorCallback, file, targetWidth, targetHeight, encodingType);
} else {
var storageFolder = getAppData().localFolder;
file.copyAsync(storageFolder, file.name, Windows.Storage.NameCollisionOption.replaceExisting).done(function (storageFile) {
if (destinationType === Camera.DestinationType.NATIVE_URI) {
successCallback('ms-appdata:///local/' + storageFile.name);
} else {
successCallback(URL.createObjectURL(storageFile));
}
successCallback(URL.createObjectURL(storageFile));
}, function () {
errorCallback("Can't access localStorage folder.");
});
Expand Down Expand Up @@ -779,7 +771,7 @@ function takePictureFromCameraWindows (successCallback, errorCallback, args) {
function savePhoto (picture, options, successCallback, errorCallback) {
// success callback for capture operation
var success = function (picture) {
if (options.destinationType === Camera.DestinationType.FILE_URI || options.destinationType === Camera.DestinationType.NATIVE_URI) {
if (options.destinationType === Camera.DestinationType.FILE_URI) {
if (options.targetHeight > 0 && options.targetWidth > 0) {
resizeImage(successCallback, errorCallback, picture, options.targetWidth, options.targetHeight, options.encodingType);
} else {
Expand Down
12 changes: 5 additions & 7 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ exports.defineAutoTests = function () {
it('camera.spec.2 should contain three DestinationType constants', function () {
expect(Camera.DestinationType.DATA_URL).toBe(0);
expect(Camera.DestinationType.FILE_URI).toBe(1);
expect(Camera.DestinationType.NATIVE_URI).toBe(2);
expect(navigator.camera.DestinationType.DATA_URL).toBe(0);
expect(navigator.camera.DestinationType.FILE_URI).toBe(1);
expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
});

it('camera.spec.3 should contain two EncodingType constants', function () {
Expand Down Expand Up @@ -140,7 +138,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
function getPictureWin (data) {
setPicture(data);
// TODO: Fix resolveLocalFileSystemURI to work with native-uri.
if (pictureUrl.indexOf('file:') === 0 || pictureUrl.indexOf('content:') === 0 || pictureUrl.indexOf('ms-appdata:') === 0 || pictureUrl.indexOf('assets-library:') === 0) {
if (pictureUrl.indexOf('file:') === 0 || pictureUrl.indexOf('content:') === 0) {
resolveLocalFileSystemURL(data, function (e) {
fileEntry = e;
logCallback('resolveLocalFileSystemURL()', true)(e.toURL());
Expand Down Expand Up @@ -174,7 +172,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
}

/**
* Select image from library using a NATIVE_URI destination type
* Select image from library
* This calls FileEntry.getMetadata, FileEntry.setMetadata, FileEntry.getParent, FileEntry.file, and FileReader.readAsDataURL.
*/
function readFile () {
Expand Down Expand Up @@ -217,7 +215,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
}

/**
* Copy image from library using a NATIVE_URI destination type
* Copy image from library
* This calls FileEntry.copyTo and FileEntry.moveTo.
*/
function copyImage () {
Expand Down Expand Up @@ -251,7 +249,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
}

/**
* Write image to library using a NATIVE_URI destination type
* Write image to library
* This calls FileEntry.createWriter, FileWriter.write, and FileWriter.truncate.
*/
function writeImage () {
Expand Down Expand Up @@ -285,7 +283,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
}

/**
* Remove image from library using a NATIVE_URI destination type
* Remove image from library
* This calls FileEntry.remove.
*/
function removeImage () {
Expand Down
3 changes: 0 additions & 3 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ interface CameraOptions {
* Defined in navigator.camera.DestinationType. Default is FILE_URI.
* DATA_URL : 0, Return image as base64-encoded string
* FILE_URI : 1, Return image file URI
* NATIVE_URI : 2 Return image native URI
* (e.g., assets-library:// on iOS or content:// on Android)
*/
destinationType?: number;
/**
Expand Down Expand Up @@ -149,7 +147,6 @@ declare var Camera: {
DestinationType: {
DATA_URL: number;
FILE_URI: number;
NATIVE_URI: number
}
Direction: {
BACK: number;
Expand Down
Loading