Phonegap Plugin:How to convert Base64 String to a PNG image in Android
The solution; This plugin that converts a Base64 PNG String and generates an image to the sdCard. Let's go!
1. The Base64 Decoder
Get this blazing fast Base64 encode/decoder class called MiGBase64. Download it from SourceForge. Create a folder called 'util' within your project's src/ folder. Place the downloaded class there.
2. The java
Create a folder called 'org/apache/cordova' within your project's src/ folder.
Create in it a Java file called "Base64ToPNG.java" with the following source code.
package org.apache.cordova;
/**
* A phonegap plugin that converts a Base64 String to a PNG file.
*
* @author mcaesar
* @lincese MIT.
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import android.os.Environment;
import java.io.*;
import org.json.JSONException;
import org.json.JSONObject;
import util.Base64;
public class Base64ToPNG extends Plugin {
@Override
public PluginResult execute(String action, JSONArray args, String callbackId) {
if (!action.equals("saveImage")) {
return new PluginResult(PluginResult.Status.INVALID_ACTION);
}
try {
String b64String = "";
if (b64String.startsWith("data:image")) {
b64String = args.getString(0).substring(21);
} else {
b64String = args.getString(0);
}
JSONObject params = args.getJSONObject(1);
//Optional parameter
String filename = params.has("filename")
? params.getString("filename")
: "b64Image_" + System.currentTimeMillis() + ".png";
String folder = params.has("folder")
? params.getString("folder")
: Environment.getExternalStorageDirectory() + "/Pictures";
Boolean overwrite = params.has("overwrite")
? params.getBoolean("overwrite")
: false;
return this.saveImage(b64String, filename, folder, overwrite, callbackId);
} catch (JSONException e) {
e.printStackTrace();
return new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
} catch (InterruptedException e) {
e.printStackTrace();
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
}
}
private PluginResult saveImage(String b64String, String fileName, String dirName, Boolean overwrite, String callbackId) throws InterruptedException, JSONException {
try {
//Directory and File
File dir = new File(dirName);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dirName, fileName);
//Avoid overwriting a file
if (!overwrite && file.exists()) {
return new PluginResult(PluginResult.Status.OK, "File already exists!");
}
//Decode Base64 back to Binary format
byte[] decodedBytes = Base64.decode(b64String.getBytes());
//Save Binary file to phone
file.createNewFile();
FileOutputStream fOut = new FileOutputStream(file);
fOut.write(decodedBytes);
fOut.close();
return new PluginResult(PluginResult.Status.OK, "Saved successfully!");
} catch (FileNotFoundException e) {
return new PluginResult(PluginResult.Status.ERROR, "File not Found!");
} catch (IOException e) {
return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
}
}
}
3. The Javascript
Write this JavaScript as Base64ToPNG.js to your project's www folder. DONT forget to include a reference to it in your html files.
/**Works on all versions prior and including Cordova 1.6.1
* by mcaesar
* MIT license
*
*/
(function() {
/* This increases plugin compatibility */
var cordovaRef = window.PhoneGap || window.Cordova || window.cordova; // old to new fallbacks
/**
* The Java to JavaScript Gateway 'magic' class
*/
function Base64ToPNG() { }
/**
* Save the base64 String as a PNG file to the user's Photo Library
*/
Base64ToPNG.prototype.saveImage = function(b64String, params, win, fail) {
cordovaRef.exec(win, fail, "Base64ToPNG", "saveImage", [b64String, params]);
};
cordovaRef.addConstructor(function() {
if (!window.plugins) {
window.plugins = {};
}
if (!window.plugins.base64ToPNG) {
window.plugins.base64ToPNG = new Base64ToPNG();
}
});
})();
4. The plugins.xml file
Add the following to res/xml/plugins.xml file
<plugin name="Base64ToPNG" value="org.apache.cordova.Base64ToPNG"/>
5. Finally, HTML examples and the parameters
<button onclick="test();">No optional params required, Cowboy.</button> </br>
<button onclick="test2();">Make PNG with some parameters</button>
<script src="Base64ToPNG.js" type="text/javascript"></script>
<script type="text/javascript">
//May have a mime-type definition or not
var myBase64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="//a red dot
function test(){
//Illustrates how to use plugin with no optional parameters. Just the base64 Image.
window.plugins.base64ToPNG.saveImage(myBase64, {},
function(result) {
alert(result);
}, function(error) {
alert(error);
});
}
//No mimetype definition example
var myOtherBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
function test2(){
//Shows how to use optional parameters
window.plugins.base64ToPNG.saveImage(myBase64, {filename:"dot.png", overwrite: true},
function(result) {
alert(result);
}, function(error) {
alert(error);
});
}
</script>
Parameters
- filename: Name of the file to be generated. By default the same as the one in url.
- folder: Name of the directory to generate the file to. By default "sdcard/Pictures"
overwrite: If the file already exists, replace it. By default false.
I hope this answers some bothering questions. Happy coding!
Phonegap - How to generate image file from base64 string?
You just need to set the src of your image to the base 64 data to view the image.
var image = document.getElementById('myImage');
image.src = "data:image/jpeg;base64," + justTheData;
Saving dataURL(base64) to file on PhoneGap (android)
You may need to request larger file quota for the file system that is big enough to hold the image. Default is typically 5 mb but may vary in the different browsers as it's not standarized.
If the length of the data-uri exceeds this (which is likely considering it's a PNG file with 33% added 33% overhead as base64) the file won't save properly.
You can request quota using the quota API:
webkitStorageInfo.requestQuota(
webkitStorageInfo.PERSISTENT
newQuotaInBytes,
quotaCallback,
errorCallback);
More details can be found here.
How to know the path file when you save canvas in localstorage in phonegap with this article
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
function gotFS(fileSystem) {
console.log("got filesystem");
console.log(fileSystem.root.fullPath);
}
function fail() {
console.log("failed to get filesystem");
}
Related Topics
How to Use Isineditmode() to See Layout with Custom View in the Editor
Android - Print Full Exception Backtrace to Log
Android Progressbar UI Custom Layout
Multiple Dex Files Define Lorg/Apache/Cordova/Buildhelper
How to Set Different Applicationid for Each Flavor Combination Using Flavordimensions
Use Roboto Font in App with Minimum API Level 14
How to Import Android Studio Project in Eclipse
Google Sceneform - Is It Deprecated? Any Replacement
Android:Split the Screen in 2 Equals Parts with 2 Listviews
Prevent Ussd Dialog and Read Ussd Response
Limit Height of Listview on Android
Detect Back Button But Don't Dismiss Dialogfragment
Getting Results of Nearby Places from User's Location Using Google Maps API in Android
How to Create a Multilingual Android Application