androidnode.jsimagebufferbytearrayoutputstream

Android ByteArrayOutputStream Base64.encodeToString save to Server as Image, How?


In android studio I used this code to convert image to byte array and send to server:

Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] byteArrayImage = baos.toByteArray();
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT); 
ServerService.sendProfileImage(encodedImage);

In node-js back-end I use this code to write data to file:

let imageBuffer = new Buffer.from(data.info, 'Base64');
fs.writeFile(fd, imageBuffer, (err, written) => {
    if(err) {
        callBack(err);
        return;
    } else{
        fs.close(fd, () => {
            callBack(null);
            return;
        });
    }
})

Note: back-end works perfect with browser and saved images show correctly, > no problem; Android data is saved too, but image is not in correct format.

But some thing is wrong and Image is not a valid file.

Image upload well, reload from server well by browser.


Solution

  • The java code produces correct Base64 image String.

    There might be an issue while sending this string to your server. Try to print your base64 string on the server end to check whether you are getting full string from the request or not. if the string is correct then try following code to save the image

    app.post('/save-image', (req, res) => {
        require("fs").writeFile("out.jpg", req.body.info, 'base64', function(err) {
            console.log(err);
        });
    })
    

    The above code uses body-parser package to access the info field.

    This is my code which i've used in Android

    import android.graphics.Bitmap
    import android.graphics.BitmapFactory
    import android.os.Bundle
    
    import android.util.Base64
    import android.util.Log
    import androidx.appcompat.app.AppCompatActivity
    import kotlinx.android.synthetic.main.activity_main.*
    import okhttp3.*
    import java.io.ByteArrayOutputStream
    import java.io.IOException
    
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            submit.setOnClickListener {
                val bitmap = BitmapFactory.decodeResource(resources, R.drawable.out)
                val baos = ByteArrayOutputStream()
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
                val imageBytes: ByteArray = baos.toByteArray()
                val imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT)
                send(imageString)
            }
    
    
        }
    
        private fun send(imageString: String) {
            val body = FormBody.Builder()
            body.add("info",imageString)
            val request = Request.Builder().url("http://192.168.1.4:3000/save-image").post(body.build())
            OkHttpClient.Builder().build().newCall(request.build()).enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    Log.e("Failure",Log.getStackTraceString(e))
                }
    
                override fun onResponse(call: Call, response: Response) {
                    Log.e("response",response.body?.string() ?: "failed")
                }
    
            })
        }
    }