Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post Base64 image to Mvc controller

Consider this base64 encode image

<img src='data:image/Png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABICAYAAABhlHJbAAAABHNCSVQICAgIfAhkiAAAAAFzUkdCAK7OHOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAABVlAAAVZQGF3cVdAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABnNJREFUeF7tnFls3EQYx11ucQshClWbtb1LC4RLIARIHAXxgsQDCOWhJGs7mypIoII4BAIhsYAEWY+TlEo8FAQSQjxAuR54AnFUFHH0CQlEEWcaQhpKmx5poVWb8H3eb92Jd7Nre8a7a2d/0l9txvN99vw1HnvtGSsdqskYzu2ayb4A7dNN9oNm2E8qPW8fT5s71EOznDwYdxQ0x0s12LtXD248kaoFpFg8TisMX6Gb9t264dwHSR5PtEz7Mc10BrE92b6RnKLMLaGWulDPO+w3ryLoje8FMlG37As1094IQX/7k6RJqsl+wdNz2WDxVDXProWyGX8dv+qamFu34WQwbz1UPOIPTLec3+HfndXltQU9+P0qE1Vr9GzY+K2/MugACAfUd8q9Mslir4M+BMO+oXb52xpYaOLq1cUTyLziKVCIJvGVtmYMdlf4gTMZ4NkGpjq+NoeTwZ51k8EA+zS/AcaG5z13U0o2zy6FtoqO8ZNKpm/0AvgP350Z7SO1kHlTXJujalqB3vZApQCvSti1aT+pJGcOdUNbZZiHegtP308qBXCJfoL2k0q6+p1LYNzbwRkgoumca /> 

I would like to post this src to Mvc controller but getting null when post with ajax here is the post method.

    var file = document.getElementById("base64image").src;

        var formdata = new FormData();
        formdata.append("base64image", file);

        $.ajax({
            url: "http://localhost:26792/home/SaveImage",
            type: "POST",
            data: file



        });

Mvc Controller

    [HttpPost]

    public void SaveImage(Image file)
    {

    }

I think the datatype I am using is not valid for this please suggest me what can I do here.

enter image description here

Full Html Code

<!doctype html>

<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebcamJS Test Page</title>
<style type="text/css">
    body { font-family: Helvetica, sans-serif; }
    h2, h3 { margin-top:0; }
    form { margin-top: 15px; }
    form > input { margin-right: 15px; }
    #results { float:right; margin:20px; padding:20px; border:1px solid; background:#ccc; }
</style>
</head>
<body>
<div id="results">Your captured image will appear here...</div>

<h1>WebcamJS Test Page</h1>
<h3>Demonstrates simple 320x240 capture &amp; display</h3>

<div id="my_camera"></div>

<!-- First, include the Webcam.js JavaScript Library -->
<script type="text/javascript" src="../webcam.min.js"></script>

<!-- Configure a few settings and attach camera -->
<script language="JavaScript">
    Webcam.set({
        width: 320,
        height: 240,
        image_format: 'jpeg',
        jpeg_quality: 90
    });
    Webcam.attach( '#my_camera' );
</script>

<!-- A button for taking snaps -->
<form>
    <input type=button id="takeshot" value="Take Snapshot" onClick="take_snapshot()">
</form>

<!-- Code to handle taking the snapshot and displaying it locally -->
<script language="JavaScript">

    window.onload = function () {

        setInterval(function () { take_snapshot() }, 5000);
    }
    function take_snapshot() {
        // take snapshot and get image data
        Webcam.snap( function(data_uri) {
            // display results in page
            document.getElementById('results').innerHTML = 
                '<h2>Here is your image:</h2>' + 
                '<img id="base64image" src="' + data_uri + '"/>';
        });



        var file = document.getElementById("base64image").src;

        var formdata = new FormData();
        formdata.append("base64image", file);

        $.ajax({
            url: "http://localhost:26792/home/SaveImage",
            type: "POST",
            data: file



        });
        //var ajax = new XMLHttpRequest();
        //ajax.addEventListener("load", function (event) { uploadcomplete(event); }, false);
        //ajax.open("POST", "http://localhost:26792/home/SaveImage");

        //ajax.send(formdata);
    }
    </script>
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


 </body>
 </html>
like image 848
TAHA SULTAN TEMURI Avatar asked Oct 21 '17 13:10

TAHA SULTAN TEMURI


2 Answers

I am not 100 % sure what your end goals are here. But the below answer explains how you can send a base64 image source string to server and save it. I tested it with a base64 string generated from a small image (22 KB size) and it worked.

In your ajax call, you should be sending the FormData object you created, not the value of file variable. Also make sure you use processData and contentType properties when making the ajax call while sending a FormData object.

var file = document.getElementById("base64image").src;

var formdata = new FormData();
formdata.append("base64image", file);

$.ajax({
    url: "@Url.Action("SaveImage")",
    type: "POST",
    data: formdata,
    processData: false,
    contentType: false
});

Now since this is the base 64 string of the image, use string as the parameter type of your action method. The parameter name should match with your formdata item key(base64Image). You can generate a byte array from the base64 string in your action method. Also the image source starts with data:image/png;base64, which needs to be removed from the string before you try to convert it.

The below method accepts the string you are sending from the client, and removes the first 21 characters and use the result of that (which is now a valid base 64 string) and then creates an image from that and saves to Content/Images/ directory in the app root with a random file name.

[HttpPost]
public void SaveImage(string base64image)
{
    if (string.IsNullOrEmpty(base64image))
        return;

    var t = base64image.Substring(22);  // remove data:image/png;base64,

    byte[] bytes = Convert.FromBase64String(t);

    Image image;
    using (MemoryStream ms = new MemoryStream(bytes))
    {
        image = Image.FromStream(ms);
    }
    var randomFileName = Guid.NewGuid().ToString().Substring(0, 4) + ".png";
    var fullPath = Path.Combine(Server.MapPath("~/Content/Images/"), randomFileName);
    image.Save(fullPath, System.Drawing.Imaging.ImageFormat.Png);
}

I am not 100 % sure that the default model binder can bind the base64 string to an image. If not, you can perhaps create one which does that and add that to the model binders in your system and then use the Image as the parameter type. The code inside model binder will be very similar ( read the string and generate image from that)

like image 194
Shyju Avatar answered Sep 26 '22 08:09

Shyju


I am using HttpPostedFileBase.cs.

 [HttpPost]
            public ActionResult AddDocument(ReservationDocumentsVM reservationDocumentsVM, HttpPostedFileBase postedFile)
            {
                if (postedFile != null)
                {
                    string path = Server.MapPath("~/Content/Documents/");

                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    postedFile.SaveAs(path + Path.GetFileName(postedFile.FileName));
                    reservationDocumentsVM.VirtualPath = path + Path.GetFileName(postedFile.FileName);

                    reservationRepository.AddOrUpdateReservationDocuments(reservationDocumentsVM);


                }


   return RedirectToAction("Index", "Reservation");
        }
like image 33
Indrit Kello Avatar answered Sep 22 '22 08:09

Indrit Kello