If anyone needs to solve this, the final code using Base64 is:
Code:
Private Sub TakePicture (TargetWidth As Int, TargetHeight As Int)
Camera.TakePicture
Wait For Camera_Complete (Success As Boolean, Image As Bitmap, VideoPath As String)
B4XPages.GetManager.mStackOfPageIds.Add(B4XPages.GetPageId(Me))
If Success Then
Dim bmp As B4XBitmap = Image
Log("TargetWidth:"&TargetWidth & ", TargetHeight:"& TargetHeight)
bmp.Resize(TargetWidth, TargetHeight, True)
GrabarImagen(bmp)
CallSubDelayed3(Me, "Image_Available", True, bmp)
Else
CallSubDelayed3(Me, "Image_Available", False, Null)
End If
End Sub
Private Sub GrabarImagen(bmp As B4XBitmap)
Dim Out As OutputStream
Out = File.OpenOutput(xui.DefaultFolder, "Test.png", False)
bmp.WriteToStream(Out, 90, "JPEG")
Out.Close
End Sub
Private Sub SwbAceptar_Click
Reingreso = 0
'Dim su As StringUtils
'Dim base64 As String = su.EncodeBase64(File.ReadBytes(ImageView1.GetBitmap))
'Dim base As String = Base64EncodeDecodeImage.ImageToString2(ImageView1.GetBitmap)
Dim base As String = Base64EncodeDecodeImage.Base64ImageToString(xui.DefaultFolder,"Test.png")
Log(base.Length)
B4XLoadingIndicator1.Show
wait for (enviarImagen(base)) complete (result As String)
B4XLoadingIndicator1.Hide
Log(result)
B4XPages.ClosePage(Me)
End Sub
Sub enviarImagen(pImagenBase64 As String) As ResumableSub
Dim j As HttpJob
'Dim parser As JSONParser
Dim JSONGenerator As JSONGenerator
Dim Parametros As Map
Dim hayError As String
hayError = ""
j.Initialize("",Me)
Parametros.Initialize
'B4XLoadingIndicator1.Show
Parametros.put("Usuario",Main.Usuario)
Parametros.Put("Imagen",pImagenBase64)
Parametros.Put("Observaciones",B4XFComentario.Text)
Parametros.Put("IdOwner",IdOwner)
Parametros.Put("Catalogo",Catalogo)
JSONGenerator.Initialize(Parametros)
j.Initialize("",Me)
j.putstring( Main.Servidor & "/imagenes", JSONGenerator.ToString )
j.GetRequest.SetContentType("application/json") ' yes, it comes after j.poststring()
wait for (j) JobDone (j As HttpJob)
If j.Success Then
'parser.Initialize(j.GetString())
hayError = "ok" & j.GetString()
Else
hayError = j.ErrorMessage
End If
j.Release
'B4XLoadingIndicator1.Hide
'Log("Cargado:"&LCuotasPrestamos)
Return hayError
End Sub
My first idea was to send the Bitmap in raw format, without passing by the device storage, but that would mind to send the picture in PNG format. This is huge, and converting it to Base64 makes it far worse (since the size of the Base64 string is Heigth * Width * Dep (32bits) * 2). Sending a picture like this takes 1.9MB and 20 seconds.
So first I save it in JPEG format and there you can adjust the Quality parameter in WriteToStream (in PNG the quality seems to do nothing). This way the 768*360 pixel picture takes 5 seconds to the server and 3.5kb.
If you still didn't realize, my code uses the Base64EncodeDecodeImage library.
Please consider that I'm still new to B4X.
NODE JS Code:
[CODE lang="javascript" title="Server Code"]// Almacena una nueva Imagen
router.put('/',(req, res,next)=> {
var Id = req.body.Usuario;
var imagen = req.body.Imagen;
var texto = req.body.Observaciones;
var idOwner = req.body.IdOwner;
var catalogo = req.body.Catalogo;
//var Respuesta = [{error:"0"}];
//console.log('Id=' + Id);
if (!Id)
{
res.status(400).send('Parametro invalido!');
return;
}
moduloSQL.executeSQL (`SELECT IsNULL(DATEDIFF(day,(select LogInDate from Sesiones where Operador='${Id}'),getdate()),99) as tiempo`,function(err,recordset) {
if (err)
{
//Respuesta[0].error = err.message;
res.status(500).send(err.message);
//console.log(err);
//return err;
}
else {
//console.log('Columas:' + recordset.recordset[0].password + '='+pClave);
//console.log('rows:'+recordset.rowsAffected);
//console.log(recordset);
if (recordset.rowsAffected > 0)
{
almacenarImagen(imagen,texto,idOwner,catalogo,res);
}
else { res.status(500).send('Sin registros');}
}});
});
function almacenarImagen(imgData,pObservaciones,pIdOwner,pCatalogo,res) {
var consulta = "";
console.log("***********************************************************")
console.log(pObservaciones);
//console.log(pImagen.length);
// var imgData = req.body.image;// coming from client request
//var base64Data = imgData.split(",")[1]; // split with `,`
var fileName = Date.now()+".jpeg";
require("fs").writeFile('./upload/images/'+fileName, imgData, 'base64',
function(err, data) {
if (err) {
res.status(401).send("Error grabando imagen en servidor!");
console.log('err', err);
} else
res.status(200).send("ok"+fileName);
});
};
[/CODE]