You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:35:32