如何将Canvas捕获的图片POST到.NET Core后端并存储到Azure?
摄像头捕获图片上传至.NET Core后端并存储到Azure的解决方案
问题背景
通过Media Capture and Streams API连接摄像头,使用Canvas捕获静态照片后,POST到.NET Core后端时,后端viewModel.UploadFiles始终为null,仅能获取Base64格式的ImageData字符串,需解决文件绑定问题并优化上传方式。
当前捕获图片代码:
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> }
方案一:直接上传File对象(推荐)
将Canvas内容转为Blob并包装成File,通过FormData上传,符合HTTP文件上传标准,传输效率更高,后端可直接绑定到IFormFile。
前端修改代码
function captureAndUpload() { const canvas = document.getElementById("img-canvas"); const context = canvas.getContext("2d"); canvas.width = 320; canvas.height = 240; context.drawImage(video, 0, 0, 320, 240); // 将Canvas内容转为Blob canvas.toBlob(function(blob) { // 创建File对象,指定文件名和类型 const capturedFile = new File([blob], "camera-photo.png", { type: "image/png" }); // 构建FormData,键名需与后端ViewModel属性名一致 const formData = new FormData(); formData.append("UploadFiles", capturedFile); // 发送AJAX请求 $.ajax({ type: "POST", url: "/Orders/Evaluation/UploadFiles", data: formData, contentType: false, // 禁止手动设置Content-Type,让浏览器自动处理 processData: false, // 禁止jQuery序列化FormData,避免破坏结构 dataType: "json", success: () => console.log("上传成功"), error: () => console.log("上传失败") }); }, "image/png"); }
后端代码(无需修改)
保持原有的TestViewModel和接口即可,ASP.NET Core会自动将FormData中的文件绑定到IFormFile:
public class TestViewModel { public IFormFile UploadFiles { get; set; } public string ImageData { get; set; } } [HttpPost("Orders/UploadFiles")] public async Task<IActionResult> UploadPhotos(TestViewModel viewModel) { // 使用viewModel.UploadFiles上传到Azure,示例: // var blobClient = _blobServiceClient.GetBlobContainerClient("your-container").GetBlobClient(Guid.NewGuid().ToString() + ".png"); // await blobClient.UploadAsync(viewModel.UploadFiles.OpenReadStream(), true); return Ok(); }
方案二:Base64字符串转IFormFile(兼容现有前端逻辑)
若不想改动前端上传方式,可在后端接收ImageData后转换为文件流,再存储到Azure。
后端修改代码
[HttpPost("Orders/UploadFiles")] public async Task<IActionResult> UploadPhotos(TestViewModel viewModel) { if (string.IsNullOrEmpty(viewModel.ImageData)) return BadRequest("未获取到图片数据"); // 将Base64字符串转为字节数组 byte[] imageBytes = Convert.FromBase64String(viewModel.ImageData); // 转为MemoryStream用于上传 using var stream = new MemoryStream(imageBytes); // 可选:转换为IFormFile对象(如需统一处理逻辑) var formFile = new FormFile(stream, 0, imageBytes.Length, "captured", "photo.png") { Headers = new HeaderDictionary(), ContentType = "image/png" }; // 上传到Azure Blob Storage示例 // var blobClient = _blobServiceClient.GetBlobContainerClient("your-container").GetBlobClient(Guid.NewGuid().ToString() + ".png"); // await blobClient.UploadAsync(stream, true); return Ok(); }
两种方案对比
- 方案一:传输效率更高(Base64比原始二进制大30%),符合标准上传流程,后端处理更简洁,优先推荐。
- 方案二:无需修改前端,适合快速兼容现有逻辑,但需额外处理Base64转流的步骤。
内容的提问来源于stack exchange,提问作者Smitty-Werben-Jager-Manjenson
相关产品推荐
相关产品推荐

