67 Commits

Author SHA1 Message Date
Gastón Cerioni
bd3e0f299f removes check code for folders 2021-12-15 17:23:02 -03:00
Stefano Magrassi
c0b74c2a75 Merge pull request #24 from Nexxa/release-4.1.3
Release 4.1.3
2017-11-09 10:43:29 +01:00
StefanoMagrassi
80aa06a6a1 version 4.1.3 2017-11-09 10:42:40 +01:00
StefanoMagrassi
771674d948 npm package-lock 2017-11-09 10:42:19 +01:00
Stefano Magrassi
51093d00b8 Merge pull request #23 from bmdelacruz/master
Fix "Ios return path" issue
2017-11-09 10:37:34 +01:00
Bryan Dela Cruz
ee4e96a1da Merge pull request #1 from telember/master
Update Base64ToGallery.m (Remove the logging of the image path)
2017-11-06 18:57:50 +08:00
Kittipong Bunmuang
8590d54633 Update Base64ToGallery.m
- fix rm path log
2017-09-05 23:27:57 +07:00
Bryan Dela Cruz
fa0558ea75 Changed callback invocation to pass image path 2017-08-23 00:13:18 +08:00
StefanoMagrassi
d270bcb1a6 Update README.md 2017-01-05 13:07:43 +01:00
StefanoMagrassi
096fada588 version 4.1.2 2016-12-15 08:54:21 +01:00
StefanoMagrassi
f2d7364e2f dependencies updated 2016-12-15 08:52:39 +01:00
StefanoMagrassi
a4b9af06be Merge pull request #15 from romankisil/master
Fixed iOS Error handling
2016-12-14 20:37:42 +01:00
Romans Kisils
a7167e2271 If permissions were declined the iOS code would still call the success callback, now the error is handled and a fail callback is called 2016-12-13 11:30:14 +00:00
StefanoMagrassi
2f531aaa0b version 4.1.1 2016-05-05 17:52:01 +02:00
StefanoMagrassi
f939db234c documentation - options.prefix 2016-05-05 17:49:46 +02:00
StefanoMagrassi
d48ac59654 version 4.1.0 2016-05-05 17:42:11 +02:00
StefanoMagrassi
73661bfde0 documentation 2016-05-05 17:35:44 +02:00
StefanoMagrassi
31676e30c9 documentation 2016-05-05 17:35:05 +02:00
StefanoMagrassi
691bd3fa40 Merge pull request #7 from bastian-meier/iosReturnPath
Ios return path
2016-05-05 17:23:35 +02:00
Bastian Meier
2cd9da795d adding to camera roll works now 2016-05-02 12:40:49 +02:00
Bastian Meier
6c09ce9084 test3 2016-05-02 12:35:48 +02:00
Bastian Meier
35bb949c91 self.imagePath is not needed anymore 2016-05-02 12:35:02 +02:00
Bastian Meier
9f9f4d0e1b test2 2016-05-02 12:34:27 +02:00
Bastian Meier
e53cf1eca4 test 2016-05-02 12:28:01 +02:00
Bastian Meier
225bd5bfc0 typo 2016-05-02 12:00:00 +02:00
Bastian Meier
faf76f2315 undeclared selector error 2016-04-20 16:52:59 +02:00
Bastian Meier
01760d5621 test16 2016-04-18 15:00:43 +02:00
Bastian Meier
d064aea90a test15 2016-04-18 14:51:25 +02:00
Bastian Meier
ff9f8edbea test14 2016-04-18 14:45:24 +02:00
Bastian Meier
b4206a4045 test13 2016-04-18 14:32:07 +02:00
Bastian Meier
c560d6ef1a test12 2016-04-18 14:20:18 +02:00
Bastian Meier
8447803226 test11 2016-04-18 14:16:02 +02:00
Bastian Meier
2fec5c863b test10 2016-04-18 14:07:01 +02:00
Bastian Meier
569fbb77c4 test9 2016-04-18 14:01:22 +02:00
Bastian Meier
ae56b05219 test8 2016-04-18 13:00:05 +02:00
Bastian Meier
80edab88e9 test7 2016-04-18 12:55:47 +02:00
Bastian Meier
39b835717c test6 2016-04-18 12:48:04 +02:00
Bastian Meier
4b40b56677 test5 2016-04-18 12:40:34 +02:00
Bastian Meier
e420a09a81 test4 2016-04-18 12:34:14 +02:00
Bastian Meier
e2695a6af6 test3 2016-04-18 12:26:47 +02:00
Bastian Meier
720458fbbc test2 2016-04-18 12:17:34 +02:00
Bastian Meier
123f36b94a test 2016-04-18 12:11:40 +02:00
Bastian Meier
e687171a32 typos 2016-04-18 11:43:24 +02:00
Bastian Meier
6b39e70581 property imagePath added 2016-04-18 11:39:40 +02:00
Bastian Meier
60aee7b9fd return image path 2016-04-18 11:27:33 +02:00
StefanoMagrassi
4dc72591ee version 4.0.0 2016-04-13 10:15:33 +02:00
StefanoMagrassi
1de7e2d5f5 Merge branch 'issue#4'
resolves #4
2016-04-13 10:14:24 +02:00
StefanoMagrassi
3e6b70dba7 manage default prefix only in js 2016-04-13 10:11:05 +02:00
StefanoMagrassi
42ee53b9e9 notes for options parameter in README 2016-04-13 10:09:52 +02:00
StefanoMagrassi
8177ea902e make requiring work 2016-04-13 09:09:26 +02:00
StefanoMagrassi
cbdd6cd3d1 Object.assign local polyfill 2016-04-12 17:52:05 +02:00
StefanoMagrassi
ba52ad27a7 media scanner option in camel case 2016-04-12 12:35:13 +02:00
Bastian Meier
92a9cc577b mediaScanner in camelcase 2016-04-12 12:34:17 +02:00
Bastian Meier
3d78e43388 options.medisScanner should be Camelcase 2016-04-12 12:34:06 +02:00
Bastian Meier
fff731c9e3 fix for 'mediaSanner wrong type'-bug 2016-04-12 12:27:16 +02:00
StefanoMagrassi
7afc399a3a update version -> bump version 2016-04-12 09:17:11 +02:00
StefanoMagrassi
03dc4f65bb updated documentation 2016-04-12 09:05:04 +02:00
StefanoMagrassi
87ffe30dd3 options object in base64ToGallery api 2016-04-12 09:04:44 +02:00
StefanoMagrassi
fdae1613eb run media scanner only if enabled through options 2016-04-11 17:09:55 +02:00
StefanoMagrassi
b56e720048 cleanup 2016-04-11 17:08:16 +02:00
StefanoMagrassi
8ae80d457c npm -> save exact version and show no progress bar 2016-04-11 15:31:22 +02:00
StefanoMagrassi
247413e97d Merge branch 'release-3.0.0' 2016-01-22 15:38:43 +01:00
StefanoMagrassi
9c482f9782 version 3.0.0 - fixes #3 2016-01-22 15:36:21 +01:00
StefanoMagrassi
2495048e3b Merge branch 'readme_updates' into issue#3 2016-01-22 15:32:39 +01:00
StefanoMagrassi
1384a7d8c1 readme updates for version 3.0.0 2016-01-22 15:32:26 +01:00
StefanoMagrassi
6152a9fcd2 edited to be compliant with cordova-ios > 3.8.0
- removed iVars in Base64ToGallery interface definition (compiler warning)
- callbackId and result class public property
- fixed wrong variables refencies and names
- background thread (previous commit, but it's important to notice it)
2016-01-21 12:18:17 +01:00
StefanoMagrassi
538f749c1b changed ios api 2016-01-21 11:20:50 +01:00
12 changed files with 1503 additions and 182 deletions

2
.npmrc
View File

@@ -1,2 +1,4 @@
git-tag-version = false git-tag-version = false
tag-version-prefix = tag-version-prefix =
save-exact = true
progress = false

View File

@@ -1,26 +1,48 @@
# Cordova base64ToGallery Plugin # :warning: DISCONTINUED - Cordova base64ToGallery Plugin
This plugin (based on [devgeeks/Canvas2ImagePlugin](http://github.com/devgeeks/Canvas2ImagePlugin)) allows you to save base64 data as a png image into the device (iOS Photo Library, Android Gallery or WindowsPhone 8 Photo Album). This plugin (based on [devgeeks/Canvas2ImagePlugin](http://github.com/devgeeks/Canvas2ImagePlugin)) allows you to save base64 data as a png image into the device (iOS Photo Library, Android Gallery or WindowsPhone 8 Photo Album).
The plugin is a kind of fork of the [solderzzc/Base64ImageSaverPlugin](https://github.com/solderzzc/Base64ImageSaverPlugin) but with a cleaner history (a.k.a: no tags from Canvas2ImagePlugin repo). The plugin is a kind of fork of the [solderzzc/Base64ImageSaverPlugin](https://github.com/solderzzc/Base64ImageSaverPlugin) but with a cleaner history (a.k.a: no tags from Canvas2ImagePlugin repo) and a newer iOS implementation.
## Alert ## Alerts
In order to be more consistent with the cordova naming convention, since version 2.0 the repository name and the cordova plugin id have changed to **cordova-base64-to-gallery** (issue #1).
### Plugin id - [issue #1](https://github.com/Nexxa/cordova-base64-to-gallery/issues/1)
In order to be more consistent with the cordova naming convention, since version 2.0 the repository name and the cordova plugin id have changed to **cordova-base64-to-gallery**.
Please uninstall the old version and reinstall the new one. Please uninstall the old version and reinstall the new one.
### cordova-ios > 3.8.0 - [issue #3](https://github.com/Nexxa/cordova-base64-to-gallery/issues/3)
According to the [documentation](https://github.com/apache/cordova-ios/blob/master/guides/API%20changes%20in%204.0.md#nsdatabase64h-removed), `NSData+Base64.h` class was removed starting from version 4.0.0 of the **cordova-ios platform** (and it was already deprecated from version 3.8.0).
So, cordova-base64-to-gallery plugin **from version 3.0.0** has changed the iOS implementation in order to support the changes in cordova-ios platform.
If you need to support cordova-ios < 3.8.0 please refer to [cordova-base64-to-gallery@2.0.2](https://github.com/Nexxa/cordova-base64-to-gallery/tree/2.0.2). There is also an "**old**" branch that might have some updates in the future (Android/WP8 fixes or something like that).
## Usage ## Usage
Call the `cordova.base64ToGallery()` method using success and error callbacks and the id attribute or the element object of the canvas to save: Call the `cordova.base64ToGallery()` method with image's base64 string, success and error callbacks (`options` is optional):
### Methods ### Methods
#### `cordova.base64ToGallery(data, [prefix, success, fail])` #### `cordova.base64ToGallery(data, [options, success, fail])`
Param | Type | Default | Description Param | Type | Default | Description
----------- | ---------- | ----------------- | ------------------ ----------- | ---------- | ----------------- | -----------------------------------------
**data** | *string* | | base64 string **data** | *string* | | base64 string
**prefix** | *string* | **img_** | file's name prefix **options** | *object* | \*see below | options
**success** | *function* | **console.log** | success callback **success** | *function* | **console.log** | success callback (file path as parameter)
**fail** | *function* | **console.error** | fail callback **fail** | *function* | **console.error** | fail callback (error as parameter)
#### Available options *
##### `prefix`
Saved file name prefix.
**Default**: "img_"
##### `mediaScanner`
On Android runs Media Scanner after file creation.
On iOS if true the file will be added to camera roll, otherwise will be saved to a library folder.
**Default**: true
### Example ### Example
@@ -29,13 +51,16 @@ function onDeviceReady() {
cordova.base64ToGallery( cordova.base64ToGallery(
base64Data, base64Data,
'img_', {
prefix: 'img_',
function(msg){ mediaScanner: true
console.log(msg);
}, },
function(err){ function(path) {
console.log(path);
},
function(err) {
console.error(err); console.error(err);
} }
); );
@@ -46,3 +71,4 @@ function onDeviceReady() {
- [Tommy-Carlos Williams](http://github.com/devgeeks) - [Tommy-Carlos Williams](http://github.com/devgeeks)
- [Simba Zhang](http://github.com/solderzzc) - [Simba Zhang](http://github.com/solderzzc)
- [StefanoMagrassi](http://github.com/StefanoMagrassi) - [StefanoMagrassi](http://github.com/StefanoMagrassi)
- [Bastian Meier](https://github.com/bastian-meier)

1196
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +1,32 @@
{ {
"name": "cordova-base64-to-gallery", "name": "@goiarlabs/cordova-base64-to-gallery",
"version": "2.0.2", "version": "6.0.0-falopa",
"description": "Cordova plugin to save base64 data as a png image into the device", "description": "Cordova plugin to save base64 data as a png image into the device",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"update": "node ./scripts/update_version", "bump": "node ./scripts/bump_version",
"lint": "eslint www/base64ToGallery.js", "lint": "eslint www/base64ToGallery.js",
"test": "npm run lint", "test": "npm run lint",
"postversion": "npm run bump",
"prepublish": "npm test" "prepublish": "npm test"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/Nexxa/cordova-base64-to-gallery.git" "url": "git+https://github.com/@goiarlabs/cordova-base64-to-gallery.git"
}, },
"bugs": { "bugs": {
"url": "https://github.com/Nexxa/cordova-base64-to-gallery/issues" "url": "https://github.com/@goiarlabs/cordova-base64-to-gallery/issues"
}, },
"engines": [ "engines": [
{ {
"cordova": ">=3.0.0" "cordova": ">=3.0.0"
}, },
{ {
"node": ">=0.10" "node": ">=0.12"
} }
], ],
"cordova": { "cordova": {
"id": "cordova-base64-to-gallery", "id": "@goiarlabs/cordova-base64-to-gallery",
"platforms": [ "platforms": [
"ios", "ios",
"android", "android",
@@ -56,7 +57,7 @@
} }
], ],
"devDependencies": { "devDependencies": {
"eslint": "1.10.3", "eslint": "3.12.2",
"nodemsg": "1.0.0" "nodemsg": "1.1.0"
} }
} }

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns:android="http://schemas.android.com/apk/res/android" xmlns="http://www.phonegap.com/ns/plugins/1.0" id="cordova-base64-to-gallery" version="2.0.2"> <plugin xmlns:android="http://schemas.android.com/apk/res/android" xmlns="http://www.phonegap.com/ns/plugins/1.0" id="cordova-base64-to-gallery" version="4.1.3">
<engines> <engines>
<engine name="cordova-ios" version="<3.8.0" /> <engine name="cordova-ios" version=">=3.8.0" />
</engines> </engines>
<name>base64ToGallery</name> <name>base64ToGallery</name>
@@ -15,6 +15,9 @@
<license>MIT</license> <license>MIT</license>
<js-module name="object.assign-polyfill" src="www/object.assign-polyfill.js">
</js-module>
<js-module name="base64ToGallery" src="www/base64ToGallery.js"> <js-module name="base64ToGallery" src="www/base64ToGallery.js">
<clobbers target="cordova.base64ToGallery"/> <clobbers target="cordova.base64ToGallery"/>
</js-module> </js-module>

View File

@@ -30,119 +30,97 @@ import android.util.Log;
*/ */
public class Base64ToGallery extends CordovaPlugin { public class Base64ToGallery extends CordovaPlugin {
// Consts // Consts
public static final String ACTION = "saveImageDataToLibrary"; public static final String EMPTY_STR = "";
public static final String DEFAULT_FILE_PREFIX = "img_";
public static final String EMPTY_STR = "";
@Override @Override
public boolean execute(String action, JSONArray args, public boolean execute(String action, JSONArray args,
CallbackContext callbackContext) throws JSONException { CallbackContext callbackContext) throws JSONException {
if (action.equals(ACTION)) { String base64 = args.optString(0);
String filePrefix = args.optString(1);
boolean mediaScannerEnabled = args.optBoolean(2);
String base64 = args.optString(0); // isEmpty() requires API level 9
String filePrefix = args.optString(1); if (base64.equals(EMPTY_STR)) {
callbackContext.error("Missing base64 string");
}
// isEmpty() requires API level 9 // Create the bitmap from the base64 string
if (base64.equals(EMPTY_STR)) { byte[] decodedString = Base64.decode(base64, Base64.DEFAULT);
callbackContext.error("Missing base64 string"); Bitmap bmp = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
}
if (filePrefix.equals(EMPTY_STR)) { if (bmp == null) {
filePrefix = DEFAULT_FILE_PREFIX; callbackContext.error("The image could not be decoded");
}
// Create the bitmap from the base64 string } else {
byte[] decodedString = Base64.decode(base64, Base64.DEFAULT);
Bitmap bmp = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
if (bmp == null) { // Save the image
callbackContext.error("The image could not be decoded"); File imageFile = savePhoto(bmp, filePrefix);
} else { if (imageFile == null) {
callbackContext.error("Error while saving image");
}
// Save the image // Update image gallery
File imageFile = savePhoto(bmp, filePrefix); if (mediaScannerEnabled) {
scanPhoto(imageFile);
}
if (imageFile == null) { callbackContext.success(imageFile.toString());
callbackContext.error("Error while saving image"); }
}
// Update image gallery return true;
scanPhoto(imageFile); }
callbackContext.success(imageFile.toString()); private File savePhoto(Bitmap bmp, String prefix) {
} File retVal = null;
return true; try {
String deviceVersion = Build.VERSION.RELEASE;
Calendar c = Calendar.getInstance();
String date = EMPTY_STR
+ c.get(Calendar.YEAR)
+ c.get(Calendar.MONTH)
+ c.get(Calendar.DAY_OF_MONTH)
+ c.get(Calendar.HOUR_OF_DAY)
+ c.get(Calendar.MINUTE)
+ c.get(Calendar.SECOND);
} else { int check = deviceVersion.compareTo("2.3.3");
return false; File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
}
}
private File savePhoto(Bitmap bmp, String prefix) { if (!folder.exists()) {
File retVal = null; folder.mkdirs();
}
try { File imageFile = new File(folder, prefix + date + ".png");
String deviceVersion = Build.VERSION.RELEASE;
Calendar c = Calendar.getInstance();
String date = EMPTY_STR
+ c.get(Calendar.YEAR)
+ c.get(Calendar.MONTH)
+ c.get(Calendar.DAY_OF_MONTH)
+ c.get(Calendar.HOUR_OF_DAY)
+ c.get(Calendar.MINUTE)
+ c.get(Calendar.SECOND);
int check = deviceVersion.compareTo("2.3.3"); FileOutputStream out = new FileOutputStream(imageFile);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
File folder; retVal = imageFile;
/* } catch (Exception e) {
* File path = Environment.getExternalStoragePublicDirectory( Log.e("Base64ToGallery", "An exception occured while saving image: " + e.toString());
* Environment.DIRECTORY_PICTURES ); //this throws error in Android }
* 2.2
*/
if (check >= 1) {
folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (!folder.exists()) { return retVal;
folder.mkdirs(); }
}
} else { /**
folder = Environment.getExternalStorageDirectory(); * Invoke the system's media scanner to add your photo to the Media Provider's database,
} * making it available in the Android Gallery application and to other apps.
*/
File imageFile = new File(folder, prefix + date + ".png"); private void scanPhoto(File imageFile) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
FileOutputStream out = new FileOutputStream(imageFile);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
retVal = imageFile;
} catch (Exception e) {
Log.e("Base64ToGallery", "An exception occured while saving image: " + e.toString());
}
return retVal;
}
/**
* Invoke the system's media scanner to add your photo to the Media Provider's database,
* making it available in the Android Gallery application and to other apps.
*/
private void scanPhoto(File imageFile) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(imageFile); Uri contentUri = Uri.fromFile(imageFile);
mediaScanIntent.setData(contentUri); mediaScanIntent.setData(contentUri);
cordova.getActivity().sendBroadcast(mediaScanIntent); cordova.getActivity().sendBroadcast(mediaScanIntent);
} }
} }

View File

@@ -2,20 +2,20 @@
// Base64ToGallery.h // Base64ToGallery.h
// Base64ToGallery PhoneGap/Cordova plugin // Base64ToGallery PhoneGap/Cordova plugin
// //
// Created by Tommy-Carlos Williams on 29/03/12. // Copyright (c) 2016 StefanoMagrassi <stefano.magrassi@gmail.com>
// Copyright (c) 2012 Tommy-Carlos Williams. All rights reserved. //
// Based on Tommy-Carlos Williams "Canvas2ImagePlugin.h"
//
// MIT Licensed // MIT Licensed
// //
#import <Cordova/CDVPlugin.h> #import <Cordova/CDV.h>
@interface Base64ToGallery : CDVPlugin @interface Base64ToGallery : CDVPlugin
{
NSString* callbackId;
}
@property (nonatomic, copy) NSString* callbackId; @property (nonatomic, copy) NSString* callbackId;
@property (nonatomic, assign) CDVPluginResult* result;
- (void)saveImageDataToLibrary:(CDVInvokedUrlCommand*)command; - (void)saveImageDataToLibrary:(CDVInvokedUrlCommand*)command;
@end @end

View File

@@ -1,9 +1,12 @@
// //
// Base64ToGallery.m // Base64ToGallery.m
// Base64ToGallery PhoneGap/Cordova plugin // Base64ToGallery PhoneGap/Cordova plugin
// //
// Created by Tommy-Carlos Williams on 29/03/12. // Copyright (c) 2016 StefanoMagrassi <stefano.magrassi@gmail.com>
// Copyright (c) 2012 Tommy-Carlos Williams. All rights reserved. //
// Based on Tommy-Carlos Williams "Canvas2ImagePlugin.m"
//
// MIT Licensed // MIT Licensed
// //
@@ -11,49 +14,89 @@
#import <Cordova/CDV.h> #import <Cordova/CDV.h>
@implementation Base64ToGallery @implementation Base64ToGallery
@synthesize callbackId;
//-(CDVPlugin*) initWithWebView:(UIWebView*)theWebView - (void)saveImageDataToLibrary:(CDVInvokedUrlCommand*)command
//{ {
// self = (Base64ToGallery*)[super initWithWebView:theWebView]; [self.commandDelegate runInBackground:^{
// return self; self.callbackId = command.callbackId;
//} self.result = nil;
- (void)saveImageDataToLibrary:(CDVInvokedUrlCommand*)command NSString *base64String = [command.arguments objectAtIndex:0];
{ NSString *prefix = [command.arguments objectAtIndex:1];
self.callbackId = command.callbackId; bool cameraRoll = [[command.arguments objectAtIndex:2] boolValue];
NSData* imageData = [NSData dataFromBase64String:[command.arguments objectAtIndex:0]];
if (base64String != nil && [base64String length] > 0) {
NSData *imageData = [[[NSData alloc] initWithBase64EncodedString:base64String options:0] autorelease];
UIImage *image = [[[UIImage alloc] initWithData:imageData] autorelease];
UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease]; // converts the UIImage to NSData
NSData *pngImageData = UIImagePNGRepresentation(image);
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); // image extension
} NSString *imageExtension = @".png";
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo // get Timestamp
{ double currentTime = CACurrentMediaTime();
CDVPluginResult* result = nil;
// Was there an error? // set fileName
if (error != NULL) { NSString *timeString = [NSString stringWithFormat:@"%f", currentTime];
NSLog(@"ERROR: %@", error); timeString = [timeString stringByReplacingOccurrencesOfString:@"." withString:@""];
NSString *fileName = [prefix stringByAppendingString: timeString];
fileName = [fileName stringByAppendingString: imageExtension];
result = [CDVPluginResult resultWithStatus: CDVCommandStatus_ERROR messageAsString:error.description]; NSString *libPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0];
NSString *libPathNoSync = [libPath stringByAppendingPathComponent:@"NoCloud"];
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
// Create the directory if necessary.
[fileManager createDirectoryAtPath:libPathNoSync withIntermediateDirectories:YES attributes:nil error:nil];
NSString *imagePath = [libPathNoSync stringByAppendingPathComponent:fileName];
[self.webView stringByEvaluatingJavaScriptFromString:[result toErrorCallbackString: self.callbackId]]; // writeToFile
bool success = [fileManager createFileAtPath:imagePath contents:pngImageData attributes:nil];
if(success){
// write to documents folder was successfull
if(cameraRoll){
// add the image to camera roll
UIImage * savedImage = [UIImage imageWithContentsOfFile:imagePath];
UIImageWriteToSavedPhotosAlbum(savedImage, self,
@selector(thisImage:hasBeenSavedInPhotoAlbumWithError:onImagePath:),
(void *) CFBridgingRetain(imagePath));
} else {
// send back the image path of the saved image
CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:imagePath];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
}else{
imagePath = [imagePath stringByAppendingString: @" - error writing image to documents folder"];
CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:imagePath];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
// No errors } else {
} else { CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no valid base64 image data was passed"];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK]; }];
[self.webView stringByEvaluatingJavaScriptFromString:[result toSuccessCallbackString: self.callbackId]];
} }
}
- (void)dealloc -(void)thisImage:(UIImage *)image hasBeenSavedInPhotoAlbumWithError:(NSError *)error onImagePath:(void*)bridgedImagePath{
{ if (error) {
[callbackId release]; CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Error saving Image to Gallery, check Permissions"];
[super dealloc]; [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
} } else {
// retrieve bridged image path and release it to get the image path
NSString *imagePath = (NSString *) CFBridgingRelease(bridgedImagePath);
// send the image path back to the js callback
CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:imagePath];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
}
@end @end

View File

@@ -22,11 +22,6 @@ public class Base64ToGallery : BaseCommand
string prefix = options[1]; string prefix = options[1];
byte[] imageBytes = Convert.FromBase64String(imageData); byte[] imageBytes = Convert.FromBase64String(imageData);
if (String.IsNullOrEmpty(prefix))
{
prefix = "img_";
}
using (var imageStream = new MemoryStream(imageBytes)) using (var imageStream = new MemoryStream(imageBytes))
{ {
imageStream.Seek(0, SeekOrigin.Begin); imageStream.Seek(0, SeekOrigin.Begin);

View File

@@ -7,48 +7,52 @@
* @license MIT * @license MIT
*/ */
/*globals cordova*/ var exec = require('cordova/exec');
var assign = require('./object.assign-polyfill');
// Consts // Consts
// ------ var SERVICE = 'Base64ToGallery';
var SERVICE = 'Base64ToGallery'; var ACTION = 'saveImageDataToLibrary';
var ACTION = 'saveImageDataToLibrary'; var ARGS = ['data', 'prefix', 'mediaScanner'];
var DEFAULTS = { prefix: 'img_', mediaScanner: true };
/**
* @property indexFromArgs - Partially applied "indexFrom" method with ARGS constant.
* @private
*/
var indexFromArgs = indexFrom.bind(null, ARGS);
// Exports
// -------
/** /**
* Saves base64 data as image. * Saves base64 data as image.
* @public
* @param {string} data * @param {string} data
* @param {string} [prefix] * @param {string} [prefix]
* @param {function} [success] * @param {function} [success]
* @param {function} [fail] * @param {function} [fail]
* @return {undefined} * @return {undefined}
*/ */
module.exports = function(data, prefix, success, fail) { module.exports = function(data, options, success, fail) {
// Handle method call with 3 or 4 parameters (prefix optional) var spec = assign(DEFAULTS, options);
if (arguments.length < 4) { var actionArgs = prepareArgs(spec);
prefix = '';
success = arguments[1];
fail = arguments[2];
}
// Prepare base64 string // Prepare base64 string
data = data.replace(/data:image\/png;base64,/, ''); data = data.replace(/data:image\/png;base64,/, '');
return cordova.exec(ok(success), error(fail), SERVICE, ACTION, [data, prefix]); // And add it to the Service's Action arguments
actionArgs.unshift(data);
return exec(ok(success), error(fail), SERVICE, ACTION, actionArgs);
}; };
// Private methods
// ---------------
/** /**
* Gets success callback if it is defined and not null. * Gets success callback if it is defined and not null.
* Otherwise returns a simple console.log. * Otherwise returns a simple console.log.
* * @private
* @param {[function|undefined|null]} success * @param {[function|undefined|null]} success
* @return {function} * @return {function}
*/ */
function ok(success) { function ok(success) {
if (typeof success === 'undefined' || success === null) { if (typeof success !== 'function') {
return console.log; return console.log;
} }
@@ -58,14 +62,53 @@ function ok(success) {
/** /**
* Gets fail callback if it is defined and not null. * Gets fail callback if it is defined and not null.
* Otherwise returns a simple console.error. * Otherwise returns a simple console.error.
* * @private
* @param {[function|undefined|null]} fail * @param {[function|undefined|null]} fail
* @return {function} * @return {function}
*/ */
function error(fail) { function error(fail) {
if (typeof fail === 'undefined' || fail === null) { if (typeof fail !== 'function') {
return console.error; return console.error;
} }
return fail; return fail;
} }
/**
* Gets index of item from array.
* @private
* @param {array} fromArr - Source array
* @param {*} item - Item
* @return {number} Index of item in array
*/
function indexFrom(fromArr, item) {
return fromArr.indexOf(item);
}
/**
* Gets value of property with specified key from object.
* @private
* @param {object} fromObj - Source object
* @param {string} key - Property key
* @return {*} Property value
*/
function valueFrom(fromObj, key) {
return fromObj[key];
}
/**
* Prepares parameter to pass to Service's Action.<br/>
* Sort options value in order to match "arguments" proto.
* @private
* @param {object} opts - Options object
* @return {array} Arguments array
*/
function prepareArgs(opts) {
var valueFromOpts = valueFrom.bind(null, opts);
return Object.keys(opts).reduce(function(acc, item) {
acc.splice(indexFromArgs(item), 0, valueFromOpts(item));
return acc;
}, []);
}

View File

@@ -0,0 +1,34 @@
if (!Object.assign) {
Object.defineProperty(Object, 'assign', {
enumerable: false,
configurable: true,
writable: true,
value: function(target) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert first argument to object');
}
var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) {
continue;
}
nextSource = Object(nextSource);
var keysArray = Object.keys(Object(nextSource));
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) {
to[nextKey] = nextSource[nextKey];
}
}
}
return to;
}
});
}
module.exports = Object.assign;