Jquery webcam plugin does not publish captured image

I am using jquery webcam plugin on MVC4 page. The plugin is here: http://www.xarg.org/project/jquery-webcam-plugin/ .

I use the save method in the plugin after capturing the image, but it is not sent to the controller action.

This is the cshtml page:

@{ ViewBag.Title = "Index"; } <!DOCTYPE html> <html lang="es"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>@ViewBag.Title - Prueba WebCam</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width" /> @Styles.Render("~/styles/base") @Scripts.Render("~/scripts/jquery", "~/scripts/jqueryui", "~/scripts/webcam") <script type="text/javascript"> $(function () { $("#camera").webcam({ width: 320, height: 240, mode: "save", swffile: "@Url.Content("~/Scripts/WebCam/jscam_canvas_only.swf")", onTick: function () { }, onSave: function () { alert('Almacenamiento realizado') }, onCapture: function () { webcam.save("@Url.Action("Save")"); alert('Captura realizada'); }, debug: function () { }, onLoad: function () { } }); }); function CaptureAndSave() { webcam.capture(); } </script> </head> <body class="home desytec"> <header> </header> <!-- MAIN --> <div id="main"> <!-- wrapper-main --> <div class="wrapper"> <!-- headline --> <div class="clear"></div> <div id="headline"> <span class="main"></span> <span class="sub"></span> </div> <!-- ENDS headline --> <!-- content --> <div id="content"> <div id="camera"></div> <br /><br /><br /> <input type="button" onclick="CaptureAndSave();" value="Capturar" /> </div> <!-- ENDS content --> </div> <!-- ENDS wrapper-main --> </div> <!-- ENDS MAIN --> <footer> </footer> </body> </html> 

And this is the controller:

 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Capture.Controllers { public class CaptureController : Controller { // // GET: /Capture/ public ActionResult Index() { return View(); } [HttpPost] public JsonResult Save(HttpPostedFileBase file) { try { if (file != null) { string pic = System.IO.Path.GetFileName(file.FileName); string path = System.IO.Path.Combine(Server.MapPath("~/Captures"), pic); file.SaveAs(path); return Json(true, JsonRequestBehavior.AllowGet); } } catch { } return Json(true, JsonRequestBehavior.AllowGet); } } } 

The save controller method is never called, and in fact, using firebug, POST is not executed.

By the way. The camera works because I see it on the canvas (DIV id = camera).

And the OnCapture callback is called after pressing the capture button.

Any help on this please?

Thanks Jaime

+6
source share
1 answer

The Save action is not called because jscam_canvas_only.swf contains only "callback" . For the full API (therefore for the "save" mode) you need to download and use jscam.swf .

So, change your webcam setting to:

 $("#camera").webcam({ //... swffile: "@Url.Content("~/Scripts/WebCam/jscam.swf")", //... }); 

Now the Save action will be called, but the file parameter will always be zero, because jscam.swf will send the image data as a hexadecimal string in the request body.

The model binding framework does not handle this by default, so you need to write additional code:

 if (Request.InputStream.Length > 0) { string pic = System.IO.Path.GetFileName("capture.jpg"); string path = System.IO.Path.Combine(Server.MapPath("~/Captures"), pic); using (var reader = new StreamReader(Request.InputStream)) { System.IO.File.WriteAllBytes(path, StringToByteArray(reader.ReadToEnd())); } return Json(true, JsonRequestBehavior.AllowGet); } 

You need to remove the file parameter and access the raw data from Request.InputStream , but since it is a hexadecimal string, you need to convert it to byte[] before saving it.

There is no built-in conversion in .NET, but SO is full of good solutions:

How to convert byte array to hexadecimal string and vice versa?

In my example, I used this method :

 public static byte[] StringToByteArray(String hex) { int NumberChars = hex.Length/2; byte[] bytes = new byte[NumberChars]; using (var sr = new StringReader(hex)) { for (int i = 0; i < NumberChars; i++) bytes[i] = Convert.ToByte(new string(new char[2]{(char)sr.Read(), (char)sr.Read()}), 16); } return bytes; } 
+1
source

All Articles