Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd3e0f299f | ||
|
|
c0b74c2a75 | ||
|
|
80aa06a6a1 | ||
|
|
771674d948 | ||
|
|
51093d00b8 | ||
|
|
ee4e96a1da | ||
|
|
8590d54633 | ||
|
|
fa0558ea75 | ||
|
|
d270bcb1a6 | ||
|
|
096fada588 | ||
|
|
f2d7364e2f | ||
|
|
a4b9af06be | ||
|
|
a7167e2271 | ||
|
|
2f531aaa0b | ||
|
|
f939db234c | ||
|
|
d48ac59654 | ||
|
|
73661bfde0 | ||
|
|
31676e30c9 | ||
|
|
691bd3fa40 | ||
|
|
2cd9da795d | ||
|
|
6c09ce9084 | ||
|
|
35bb949c91 | ||
|
|
9f9f4d0e1b | ||
|
|
e53cf1eca4 | ||
|
|
225bd5bfc0 | ||
|
|
faf76f2315 | ||
|
|
01760d5621 | ||
|
|
d064aea90a | ||
|
|
ff9f8edbea | ||
|
|
b4206a4045 | ||
|
|
c560d6ef1a | ||
|
|
8447803226 | ||
|
|
2fec5c863b | ||
|
|
569fbb77c4 | ||
|
|
ae56b05219 | ||
|
|
80edab88e9 | ||
|
|
39b835717c | ||
|
|
4b40b56677 | ||
|
|
e420a09a81 | ||
|
|
e2695a6af6 | ||
|
|
720458fbbc | ||
|
|
123f36b94a | ||
|
|
e687171a32 | ||
|
|
6b39e70581 | ||
|
|
60aee7b9fd | ||
|
|
4dc72591ee | ||
|
|
1de7e2d5f5 | ||
|
|
3e6b70dba7 | ||
|
|
42ee53b9e9 | ||
|
|
8177ea902e | ||
|
|
cbdd6cd3d1 | ||
|
|
ba52ad27a7 | ||
|
|
92a9cc577b | ||
|
|
3d78e43388 | ||
|
|
fff731c9e3 | ||
|
|
7afc399a3a | ||
|
|
03dc4f65bb | ||
|
|
87ffe30dd3 | ||
|
|
fdae1613eb | ||
|
|
b56e720048 | ||
|
|
8ae80d457c | ||
|
|
247413e97d | ||
|
|
9c482f9782 | ||
|
|
2495048e3b | ||
|
|
1384a7d8c1 | ||
|
|
6152a9fcd2 | ||
|
|
538f749c1b |
2
.npmrc
2
.npmrc
@@ -1,2 +1,4 @@
|
|||||||
git-tag-version = false
|
git-tag-version = false
|
||||||
tag-version-prefix =
|
tag-version-prefix =
|
||||||
|
save-exact = true
|
||||||
|
progress = false
|
||||||
|
|||||||
56
README.md
56
README.md
@@ -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
1196
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|||||||
34
www/object.assign-polyfill.js
Normal file
34
www/object.assign-polyfill.js
Normal 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;
|
||||||
Reference in New Issue
Block a user