1

I'm using the Media Capture and Streams API to connect to webcams and other peripheral cameras. We use the cameras to take still photos. My question is how can I POST or upload those photos to the server?

I'm capturing photos like so:

captureImage: function () {
    // canvas is just a <canvas> element
    const context = canvas.getContext("2d");
    canvas.width = 320;
    canvas.height = 240;
    context.drawImage(video, 0, 0, 320, 240); // video is a <video> tag with live feed of camera
    return canvas.toDataURL("image/png"); // can be used to set src of <img>
}

How can I POST the image to my .net endpoint so I can save it in Azure? So far I have tried:

    var imageData = document.getElementById("img-canvas").toDataURL("image/png");
    imageData = imageData.replace('data:image/png;base64,', '');

    var TestViewModel = {
        UploadFiles: document.getElementById("img-canvas").toDataURL("image/png"),
        ImageData: imageData
    }

    $.ajax({
        type: "POST",
        url: "/Orders/Evaluation/UploadFiles",
        data: TestViewModel, //JSON.stringify(TestViewModel),
        //contentType: 'application/json',
        dataType: "json",
        async: true,
        success: function (response) {
            console.log("success");
        },
        error: function (response) {
            console.log("fail");
        },
    });

On the server side, I have a simple endpoint setup:

[HttpPost("Orders/UploadFiles")]
public async Task<IActionResult> UploadPhotos(TestViewModel viewModel)
{
    // save photo to Azure
}

And the TestViewModel looks like:

public class TestViewModel
{
    public IFormFile UploadFiles { get; set; }
    public string ImageData { get; set; }
}

The problem I'm having is the viewModel.UploadFiles is always null. The viewModel.ImageData is a string that I need to convert into a file. I don't know if either of these options is even appropriate or if there is a better way to upload captured images that aren't yet files.

1 Answers1

1

The best option I have found is to send images as FormData.

First, you need to convert your base64string to a blob and post that blob as FormData. Then, you need to catch that file as IFormFile on the dotnet side.

function convertBase64ToBlob(base64Image) {
    // Split into two parts
    var parts = base64Image.split(';base64,');

    // Hold the content type
    var imageType = parts[0].split(':')[1];

   // Decode Base64 string
    var decodedData = window.atob(parts[1]);

    // Create UNIT8ARRAY of size same as row data length
    var uInt8Array = new Uint8Array(decodedData.length);

   // Insert all character code into uInt8Array
    for (var i = 0; i < decodedData.length; ++i) {
        uInt8Array[i] = decodedData.charCodeAt(i);
    }

    // Return BLOB image after conversion
    return {
        blob: new Blob([uInt8Array], { type: imageType }),
        type: imageType
    }
}
function postImage(imageBlobData) {
    var formData = new FormData();
    var imageBlob = {
        blob: imageBlobData.blob,
        fileName: ('testImage' + imageBlobData.type.replace('image/', ''))
    }
    formData.append('imageFile', imageBlob.blob, imageBlob.fileName);
    $.ajax({
        url: '/Orders/UploadFiles',
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
        success: function (response) {
            // Handle success
        },
        error: function (error) {
            // Handle error
        }
     });
}
var imageData = document.getElementById("img-canvas").toDataURL();
var blobData = convertBase64ToBlob(imageData);
postImage(blobData);

On the server side

[HttpPost("Orders/UploadFiles")]
public async Task<IActionResult> UploadImage(IFormFile imageFile)
{
    try
    {
        if (imageFile != null && imageFile.Length > 0)
        {
            // Read the file stream
            using (var memoryStream = new MemoryStream())
            {
                imageFile.CopyTo(memoryStream);
                byte[] imageBytes = memoryStream.ToArray();
                string fileName = imageFile.FileName;

                //save image

                return Json(new { success = true, message = "Image uploaded successfully." });
            }
        }
        else 
        {
            return Json(new { success = false, message = "No image file received." });
        }
    }
    catch (Exception ex)
    {
        return Json(new { success = false, message = "An error occurred: "  ex.Message });
    }
}
Nafis Islam
  • 1,483
  • 1
  • 14
  • 34