2012-07-09 26 views

Respuesta

24

La solución; Este complemento que convierte una Cadena PNG Base64 y genera una imagen en la tarjeta SD. ¡Vamonos!

1. La base 64 Decodificador

Obtener esta base 64 rápida clase de codificación/decodificador ardiente llamada MiGBase64. Descárguelo desde el SourceForge. Crea una carpeta llamada 'util' dentro de src/folder de tu proyecto. Coloque la clase descargada allí.

2. La java

Crear una carpeta llamada 'org/apache/cordova' dentro de src/carpeta de su proyecto. Crea en él un archivo Java llamado "Base64ToPNG.java" con el siguiente código fuente.

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. El Javascript

escribir esta JavaScript como Base64ToPNG.js a la carpeta www de su proyecto. NO olvide incluir una referencia en sus archivos html.

/**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. El archivo plugins.xml

Agregue lo siguiente al res/xml/plugins.xml presentar

<plugin name="Base64ToPNG" value="org.apache.cordova.Base64ToPNG"/> 

5. Por último, ejemplos HTML y los parámetros

<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> 

Parámetros

  1. nombre: Nombre del archivo a generar. Por defecto es el mismo que el de url.
  2. carpeta: Nombre del directorio para generar el archivo. Por defecto "sdcard/Pictures"
  3. sobrescribe: Si el archivo ya existe, sustitúyalo. Por defecto falso.

    espero que esto responda a algunas preguntas molestando. Feliz codificación!

+1

gracias. ¡Me ahorraste horas calculando cómo funcionaría esto! Hice algunas pequeñas modificaciones para admitir archivos mp3 en lugar de PNG. ¡¡¡¡Gracias de nuevo!!!! – ElHacker

+0

@mcaesar Muchas gracias, tengo todo listo excepto por una línea: byte [] decodedBytes = Base64.decode (b64String.getBytes()); me da el siguiente error: El método de decodificación (byte [], int) en el tipo Base64 no es aplicable para los argumentos (byte []) Como no soy profesional en Java, ¿podría ayudarme? Lo agradecería – MarkSmits

+0

Hola @Mark. Por favor, asegúrese de que su cadena base64 esté bien formateada. Ver ejemplos que proporcioné Gracias. – mukama

2

Esta solución solo funciona al alimentar una cadena CLEAN Base64. En otras palabras, la parte "data: image/png; base64" debe eliminarse o el llenado del decodificador Base64 falla, causando un error de nullpointer al escribir el archivo.

También noté que la imagen no aparece en la Galería, pero está almacenada correctamente en la tarjeta SD. Cuando lo descargo en mi PC, puedo abrirlo muy bien. No estoy seguro de qué se trata.

¡Gracias por el trabajo!

+0

Gracias por las correcciones. Editado el java para soportar "data: image/png; base64" completo. En cuanto a la imagen que no aparece en la galería, Android indexa los archivos multimedia solo cuando las unidades de almacenamiento cambian de estado, por ejemplo, de encendido a apagado. – mukama

+0

@mcaesar Tengo 3 preguntas acerca de su complemento: 1. Encontré que el parámetro "carpeta" debería ser: sdcard/somedirectory_name en lugar de "somedirectory_name". 2.I establecer un punto de interrupción en el instrumento: byte [] decodedBytes = Base64.decode (b64String.getBytes()); en Base64ToPNG.java. Y encontré que el código Base64.de (~) devuelve un NULL. 3. En su descripción, dijo "Coloque la clase descargada allí", pero solo obtengo el archivo: Base64.java. ¿Hay algún problema? Realmente necesito su complemento para convertir mi lienzo a un archivo .png, guardándolo en el sistema local. Por favor, dame alguna orientación. – Stallman

+0

@mcaesar Usted mencionó que corrige el archivo java para que sea compatible con la "data: image/png; base64" completa, pero me temo que olvidó cargar el archivo editado. Gracias. – Stallman

3

Fo cualquiera que quiera usar esto con kineticjs, las siguientes obras un regalo:

function saveCanvas() { 
    $('#save').bind($bind, function(){ 
     stage.toDataURL({ 
     callback: function(dataUrl){ 
      window.plugins.base64ToPNG.saveImage(dataUrl.substr(22,dataUrl.length), {}, 
       function(result) { 
        alert(result); 
       }, function(error) { 
        alert(error); 
       } 
      ); 
     }, 
      mimeType: 'image/png', 
      quality: 0.5 
     }); 
    }); 
} 
Cuestiones relacionadas