2012-07-09 10 views

risposta

24

La soluzione; Questo plugin converte una stringa PNG Base64 e genera un'immagine nella sdCard. Andiamo!

1. La Base64 Decoder

Ottenere questo velocissimo Base64 classe di codifica/decodifica chiamato MiGBase64. Scaricalo da SourceForge. Crea una cartella chiamata 'util' all'interno della cartella src/del tuo progetto. Inserisci qui la classe scaricata.

2. Il java

Creare una cartella denominata 'org/apache/Cordova' all'interno src/cartella del progetto. Creare in esso un file Java chiamato "Base64ToPNG.java" con il seguente codice sorgente.

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

Scrivi questa JavaScript come Base64ToPNG.js nella cartella www del progetto. NON dimenticare di includere un riferimento ad esso nei tuoi file 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. Il file plugins.xml

Aggiungere il seguente alla res/xml/plugins.xml presentare

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

5. Infine, esempi HTML ei parametri

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

Parametri

  1. nome: nome del file da generare. Di default è lo stesso di quello in url.
  2. cartella: nome della directory in cui generare il file. Per impostazione predefinita "sdcard/Pictures"
  3. sovrascrivi: Se il file esiste già, sostituirlo. Di default falso.

    Spero che questo risponda a qualche domanda di disturbo. Buona programmazione!

+1

grazie. Mi hai risparmiato ore a capire come avrebbe funzionato !! Ho apportato alcune piccole modifiche per supportare i file mp3 anziché PNG. Grazie ancora!!!! – ElHacker

+0

@mcaesar Grazie mille, ho preparato tutto tranne una riga: byte [] decodedBytes = Base64.decode (b64String.getBytes()); mi dà il seguente errore: Il metodo decodifica (byte [], int) nel tipo Base64 non è applicabile per gli argomenti (byte []) Dato che non sono un professionista in Java potresti aiutarmi? Lo apprezzerei. – MarkSmits

+0

Ciao @ Mark. Assicurati che la tua stringa base64 sia ben formattata. Vedi esempi che ho fornito. Grazie. – mukama

2

Questa soluzione funziona solo quando si alimenta una stringa Base64 CLEAN. In altre parole, la parte "data: image/png; base64," deve essere rimossa o il riempimento del decodificatore Base64 fallisce, causando un errore di nullpointer durante la scrittura del file.

Inoltre ho notato che l'immagine non viene visualizzata nella Galleria ma è memorizzata correttamente sulla scheda SD. Quando lo scarico sul mio PC posso aprirlo bene. Non so di cosa si tratta.

Grazie per il lavoro!

+0

Grazie per le correzioni. Modificato java per supportare "data: image/png; base64" completo. Per quanto riguarda l'immagine che non appare nella galleria, Android indicizza i file multimediali solo quando le unità di archiviazione cambiano stato, ad esempio da on a off. – mukama

+0

@mcaesar Ho 3 domande sul plug-in: 1. Ho trovato che il parametro "cartella" dovrebbe essere: sdcard/nome_sedezione anziché "nome_sottore_directory". 2.Impostato un punto di interruzione nello strumento: byte [] decodificatoBytes = Base64.decode (b64String.getBytes()); in Base64ToPNG.java. E ho trovato che Base64.decode (~) restituisce un valore NULL. 3. Nella tua descrizione hai detto "Posiziona la classe scaricata lì", ma ottengo solo il file: Base64.java. C'è qualcosa che non va? Ho davvero bisogno del tuo plugin per convertire la mia tela in file .png, salvandola nel sistema locale. Per favore, dammi una guida. – Stallman

+0

@mcaesar Hai accennato al fatto che correggi il file java per supportare l'intero "data: image/png; base64", ma temo che tu abbia dimenticato di caricare il file modificato. Grazie. – Stallman

3

Fo chiunque voglia usare questo con kineticjs, il seguente funziona a meraviglia:

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 
     }); 
    }); 
} 
Problemi correlati