Ayuda con Base64


([N4] Ramon Denuc) #1

Hola Foro,

Llevo casi una semana intentando guardar una imagen Base64 a un archivo convencional, ya que esa imagen la necesito utilizar en otro lado del programa.

En el programa tengo una tabla que incluye entre otros un campo llamado IMAGEN64 (con el tipo Objet.Texto) que contiene toda la parrafada de la imagen.

El código que estoy utilizando y que encontré por el foro es el siguiente:


importClass("VImage");
importClass("VByteArray");

//cadena recibida en base64 de la imagen.
var B64 = theRoot.varToString( "IMAGEN64" );

//ruta para guardar la imangen.
var PATH = theRoot.varToString( "CPATH" );

// Desde una cadena Base64 obtenemos una imagen
var oTexto = new VByteArray();
var oByteArray = new VByteArray();
var oImage = new VImage();

// Cadena Base64 con la imagen
var cBase64 = B64;
// Cargamos el Texto en Base64
oTexto.setText(cBase64);

// Obtenemos el ByteArray con el contenido original de la imagen
oByteArray.fromBase64(oTexto);

var PathImagen = PATH;
oImage.loadFromData(oByteArray,'PNG');
oImage.save(PathImagen);

Sobre JS digamos que no tengo casi ni idea y la verdad no se si este código esta bien, y hace la que realmente tiene que hacer, que seria leer el código de la imagen y pasarlo a un archivo PNG

Así que a los que domináis JS, os pido por favor si el código que os presento esta bien, o mejor, si alguno tiene algún trozo de código para poderme mostrar como se realiza, se lo agradeceré algún día que nos podemos ver, con un par de cervecitas.

Saludos


([N1] desarrollo) #2

Buenas!

Mira en este hilo. Yo metí un post para pasar una imagen entre servidores haciendo una exportación a Base64

Saludos,

César

https://velneo.es/foros/topic/guardar-imagen-desde-javascript/


([N4] Ramon Denuc) #3

Hola Cesar,

He intentado seguir tu hilo, pero no he sabido entenderlo, en algunas partes. (Mi nivel de JS es prácticamente nulo).

De todos modos creo que el código que os puse y que a continuación os vuelvo a poner, entre otras cosas no consigo obtener la cadena en base64.


importClass("VImage");
importClass("VByteArray");

// Desde una cadena Base64 obtenemos una imagen en memoria
var oTexto = new VByteArray();
var oByteArray = new VByteArray();
var oImage = new VImage();
// Formulario contenedor
var oForm = theRoot.dataView();
//cadena recibida en base64 de la imagen.
var cBase64 = theRoot.varToString( "IMAGEN64" );

<strong>// En el siguiente Alert se deberia visualizar la cadena, pero sale vacia.
alert(cBase64);</strong>

// Cargamos el Texto en Base64
oTexto.setText(cBase64);
// Obtenemos el ByteArray con el contenido original de la imagen
oByteArray.fromBase64(oTexto);

//ruta para guardar la imangen.
var PATH = theRoot.varToString( "CPATH" );

var PathImagen = PATH;
oImage.loadFromData(oByteArray,'PNG');
oImage.save(PathImagen);

Agradecería ayuda para poder pasar una cadena Base64 a un archivo PNG

Saludos




([N4] Infortic) #4

Hola Ramón.

Conseguiste arreglar ésto?

He intentado ahcer lo mismo y me falla:

var cBase64 = theRoot.varToString( “IMAGEN64” );

No carga la variable, se queda vacía, no sé si es que no cabe o qué, el proceso que lo llama tiene la variable bien cargada y al pasarle el contenido a js se vacía…

Alguien tiene alguna idea?


([N4] Infortic) #5

Hola.

Perdón, no es cierto, la variable se recibe bien, es al cargar el bytearray.

No consigo cargarlo de la siguiente forma:

// ENTRADA: BASE64_IMG: Textod e la imagen en base 64
//          FICHERO: Senda del fichero de salida
//          FORMATO: Formato del fichero: JPG,PNG,GIF...
// RETORNO  RESULT: 0 No creado, 1 creado

importClass("VImage");
importClass("VByteArray");

var cBase64 = theRoot.varToString( "BASE64_IMG" );
var fichero = theRoot.varToString( "FICHERO" );
var formato = theRoot.varToString( "FORMATO" );

// Este alert saca el base64 sin problemas
alert(cBase64);

var oByteArray = new VByteArray();
oByteArray.fromBase64(cBase64);

// Este alert saca cadena vacía, no ha cargado el base64
alert(oByteArray.toLatin1String());
// tamaño 0
alert(oByteArray.length);

// Esto ya no funciona porque no tengo ByteArray
var oImage = new VImage();
oImage.loadFromData(oByteArray,formato);
var resulto = oImage.save(fichero,formato,-1);

theRoot.setVar("RESULT",result);

A Alguien se le ocurre que puede estar pasando?


([N3] pacosatu) #6

Hola Infortic.

Por favor, tened mucho cuidado cuando copiáis código del foro.
Vuelvo a poner el código correcto que funciona perfectamente.


// Obtener un fichero de Imagen en disco desde un String codificado en Base64
// Necesitamos cargar la clase VImage
importClass("VImage");

// Necesitamos 2 objetos VByteArray, uno que recoja el estring Base64 y otro que decodifica el base64 a Binario
var oTexto = new VByteArray();
var oByteArray = new VByteArray();
var oForm = theRoot.dataView();
var oImage = new VImage();

// Obtenemos el string con la imagen codificada en Base64
var cBase64 = theRegisterIn.fieldToString("CADENA_B64");

// Rellenamos un VByteArray con el string Base64
oTexto.setText(cBase64);
// alert(oTexto.toLatin1String());

// Obtenemos el ByteArray original del PNG
//  ¡¡OJO!!  Esto está mal documentado en la ayuda de Velneo y es lo que hace fallar tu código
oByteArray.fromBase64(oTexto);

// Guardamos la imagen a disco. 
// El programador debe conocer de antemano el formato de la imagen (no se puede deducir del base64)
if (oImage.loadFromData(oByteArray,'PNG')) {
	var cPath = theMainWindow.fileDialogGetSaveFileName("Guardar imagen",theApp.clientCachePath(), "*.png");
	oImage.save(cPath)
}
else {
	alert("No se puede guardar la Imagen");
};

Si hay algún paso concreto que no entiendes lo cuento con más detalle, pero creo que el proceso es muy sencillo.
Aquí ya no se trata de saber javascript sino de entender el API de objetos de Velneo.
Desde luego, la poca documentación de calidad existente poco ayudan, pero es lo que hay.

Saludos
Paco Satué


([N4] Infortic) #7

Gracias Paco.

Entonces fromBase64 tiene como parámetro un bytearray en lugar de un string como le estoy pasando, no me había dado cuenta.

Lo pruebo y te digo.


([N4] Infortic) #8

Perfecto como siempre Paco. Gracias

Mi código final:

// ENTRADA: BASE64_IMG: Textod e la imagen en base 64
//          FICHERO: Senda del fichero de salida
//          FORMATO: Formato del fichero: JPG,PNG,GIF...
// RETORNO  RESULT: 0 No creado, 1 creado

importClass("VImage");
importClass("VByteArray");

var cBase64 = theRoot.varToString( "BASE64_IMG" );
var fichero = theRoot.varToString( "FICHERO" );
var formato = theRoot.varToString( "FORMATO" );

var oTexto = new VByteArray();
oTexto.setText(cBase64);

var oByteArray = new VByteArray();
oByteArray.fromBase64(oTexto);

var oImage = new VImage();
if(oImage.loadFromData(oByteArray,formato)){
	var result = oImage.save(fichero,formato,-1);	
}

theRoot.setVar("RESULT",result);

Esto no funciona con GIF (que era el que estaba probando, la función save da error con GIF, la documentación de VImage dice que ese formato es sólo lectura, si no se te ocurre leerlo bien te vuelves loco (que es lo que me ha pasado).

Un saludo