将 Base64 图像发布到 Mvc 控制器

Posted

技术标签:

【中文标题】将 Base64 图像发布到 Mvc 控制器【英文标题】:Post Base64 image to Mvc controller 【发布时间】:2018-04-02 11:59:09 【问题描述】:

考虑这个 base64 编码图像

<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 /> 

我想将这个 src 发布到 Mvc 控制器,但是当使用 ajax 发布时得到 null 这里是 post 方法。

    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 控制器

    [HttpPost]

    public void SaveImage(Image file)
    

    

我认为我使用的数据类型对此无效,请建议我在这里可以做什么。

完整的 HTML 代码

<!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>

【问题讨论】:

首先,这是图像的有效 base64 字符串吗?你能创建一个渲染图像的 jsfiddle 吗? @Shyju 这是一张有效的图片,出于安全原因,我刚刚删除了一些字符,请帮忙。我的意思是,我不想显示真实图片。 src太长,这里就不写了,所以我用了小例子 @DumpsterDiver 使用字符串作为数据类型怎么样?然后您可以将该 base64 字符串转换为控制器中的图像 @Niladri 它也收到 null 【参考方案1】:

我不能 100% 确定您的最终目标是什么。但下面的答案解释了如何将 base64 图像源字符串发送到服务器并保存。我使用从small image (22 KB size) 生成的 base64 字符串对其进行了测试,并且成功了。

在您的 ajax 调用中,您应该发送您创建的 FormData 对象,而不是 file 变量的值。还要确保在发送 FormData 对象时进行 ajax 调用时使用 processDatacontentType 属性。

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

现在,由于这是图像的 base 64 字符串,因此请使用 string 作为操作方法的参数类型。参数名称应与您的表单数据项键(base64Image)匹配。您可以在您的操作方法中从 base64 字符串生成一个字节数组。此外,图像源以 data:image/png;base64, 开头,在您尝试转换之前需要将其从字符串中删除。

以下方法接受您从客户端发送的字符串,并删除前 21 个字符并使用其结果(现在是有效的 base 64 字符串),然后从中创建图像并保存到 @987654330应用根目录中的@目录,文件名随机。

[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);

我不是 100% 确定默认模型绑定器可以将 base64 字符串绑定到图像。如果没有,您也许可以创建一个执行此操作的并将其添加到系统中的模型绑定器中,然后使用 Image 作为参数类型。模型绑定器中的代码将非常相似(读取字符串并从中生成图像)

【讨论】:

抱歉@Shyju 仍然为空,感谢您的关注,非常感谢。 我实际上在答案中使用了完全相同的代码,并验证它可以正常工作。您是否按照原样遵循了答案? (客户端和服务器端) 您在 ajax POST 中调用 SaveImage 但操作是 SaveImage2? 是的。那是一个错字。我会解决的 我发送的是文件而不是表单数据,非常感谢。【参考方案2】:

我正在使用 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");
        

【讨论】:

在这种情况下,reservationDocumentsVM 是什么?我没有传递两个论点。

以上是关于将 Base64 图像发布到 Mvc 控制器的主要内容,如果未能解决你的问题,请参考以下文章

显示大型 Base64 图像 MVC 4 DOTNET

如何获取 BMP 格式图像的 Base64 字符串

VichUploader和CroppieJS:如何发送base64裁剪图像以在Symfony 4中保留

如何将图像文件和表单数据从 Ajax 传递到 MVC 控制器

如何使用 Ajax 以数组格式将多个图像从 MVC 视图发送到控制器?

如何使用 Axios 将图像从 VueJS 上传到 Symfony?