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.
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 });
}
}