Webcam image directly for attaching a file

So, I have a form, and in this form the user can upload an image. As an alternative, I want them to be able to take a picture and upload it instead.


Now I believe that when the user takes a picture with some interface of the webcam flash memory, this image should be stored in some kind of intermediate memory when the user fills out his form.

Is there any way around this? What is the best solution?

I believe that there are only two options.

Either (a) I hold a temporary photo and then take it again after the form is submitted, or (b) the user takes a photo, it is uploaded to their local machine, and they must select it as a file that will be presented again.

None of these solutions are really satisfactory to me, so I wanted to know if there is a better way to do this.

Edit: As an added bonus, although not very relevant, I am making a Rails application with Paperclip for file attachments. Also, I prefer working with jQuery ...

Also just good opinions from experienced web user interface developers would be good.

+6
source share
2 answers

I used this: http://www.xarg.org/project/jquery-webcam-plugin/ in my rails application to capture webcam image. You can download this jQuery-webcam here: https://github.com/infusion/jQuery-webcam

Here is an example implementation, sorry for the messy code:

class PicturesController < ApplicationController require 'base64' def capture # do something render :layout => "webcam" end def save_image image = params[:capture][:image] File.open("#{Rails.root}/public/path_you_want_to_image/image_name.png", 'wb') do |f| f.write(Base64.decode64(image)) end # Or use paperclip to save image for a model instead!! end end 

views / layouts / webcam.html.erb

 <!DOCTYPE html> <html> <head> <title>Application Name</title> <%= stylesheet_link_tag :all %> <%= javascript_include_tag :defaults %> <%= javascript_include_tag "http://www.google-analytics.com/ga.js"%> <%= javascript_include_tag "http://code.jquery.com/jquery-1.4.2.min.js"%> <%= javascript_include_tag "jquery.webcam"%> <script> !window.jQuery && document.write('<script src="jquery-1.4.3.min.js"><\/script>'); </script> <%= csrf_meta_tag %> </head> <body> <%= yield %> </body> </html> 

view / photos / capture.html.erb

  <div id="webcam"> <p>Capture image here!</p> </div> <%= form_for(save_image_pictures_path, :method => "post", :remote => true) do |f|%> <%= hidden_field(:item, :sku)%> <div id="capture_images"><input id="capture_image" type="hidden" value="" name="capture[image]"></div> <%= submit_tag "Capture Image", :onClick=>"javascript:capture_image();"%> <% end %> <%= link_to "Back", root_path %> <p> <canvas id="canvas" width="320" height="240"></canvas> </p> <script type="text/javascript"> var pos = 0; var ctx = null; var cam = null; var image = null; var filter_on = false; var filter_id = 0; function changeFilter() { if (filter_on) { filter_id = (filter_id + 1) & 7; } } function capture_image(){ webcam.capture(); changeFilter(); void(0); var canvas = document.getElementById('canvas') var context = canvas.getContext("2d"); var img = canvas.toDataURL("image/png"); var item_image = img.replace(/^data:image\/(png|jpg);base64,/, "") ; document.getElementById('capture_images').innerHTML="<input id=\"capture_image\" type=\"hidden\" value=\""+item_image+"\" name=\"capture[image]\">"; } function toggleFilter(obj) { if (filter_on =!filter_on) { obj.parentNode.style.borderColor = "#c00"; } else { obj.parentNode.style.borderColor = "#333"; } } jQuery("#webcam").webcam({ width: 320, height: 240, mode: "callback", swffile: "/javascripts/jscam_canvas_only.swf", onTick: function(remain) { if (0 == remain) { jQuery("#status").text("Cheese!"); } else { jQuery("#status").text(remain + " seconds remaining..."); } }, onSave: function(data) { var col = data.split(";"); var img = image; if (false == filter_on) { for(var i = 0; i < 320; i++) { var tmp = parseInt(col[i]); img.data[pos + 0] = (tmp >> 16) & 0xff; img.data[pos + 1] = (tmp >> 8) & 0xff; img.data[pos + 2] = tmp & 0xff; img.data[pos + 3] = 0xff; pos+= 4; } } else { var id = filter_id; var r,g,b; var r1 = Math.floor(Math.random() * 255); var r2 = Math.floor(Math.random() * 255); var r3 = Math.floor(Math.random() * 255); for(var i = 0; i < 320; i++) { var tmp = parseInt(col[i]); /* Copied some xcolor methods here to be faster than calling all methods inside of xcolor and to not serve complete library with every req */ if (id == 0) { r = (tmp >> 16) & 0xff; g = 0xff; b = 0xff; } else if (id == 1) { r = 0xff; g = (tmp >> 8) & 0xff; b = 0xff; } else if (id == 2) { r = 0xff; g = 0xff; b = tmp & 0xff; } else if (id == 3) { r = 0xff ^ ((tmp >> 16) & 0xff); g = 0xff ^ ((tmp >> 8) & 0xff); b = 0xff ^ (tmp & 0xff); } else if (id == 4) { r = (tmp >> 16) & 0xff; g = (tmp >> 8) & 0xff; b = tmp & 0xff; var v = Math.min(Math.floor(.35 + 13 * (r + g + b) / 60), 255); r = v; g = v; b = v; } else if (id == 5) { r = (tmp >> 16) & 0xff; g = (tmp >> 8) & 0xff; b = tmp & 0xff; if ((r+= 32) < 0) r = 0; if ((g+= 32) < 0) g = 0; if ((b+= 32) < 0) b = 0; } else if (id == 6) { r = (tmp >> 16) & 0xff; g = (tmp >> 8) & 0xff; b = tmp & 0xff; if ((r-= 32) < 0) r = 0; if ((g-= 32) < 0) g = 0; if ((b-= 32) < 0) b = 0; } else if (id == 7) { r = (tmp >> 16) & 0xff; g = (tmp >> 8) & 0xff; b = tmp & 0xff; r = Math.floor(r / 255 * r1); g = Math.floor(g / 255 * r2); b = Math.floor(b / 255 * r3); } img.data[pos + 0] = r; img.data[pos + 1] = g; img.data[pos + 2] = b; img.data[pos + 3] = 0xff; pos+= 4; } } if (pos >= 0x4B000) { ctx.putImageData(img, 0, 0); pos = 0; } }, onCapture: function () { webcam.save('/product_capture'); jQuery("#flash").css("display", "block"); jQuery("#flash").fadeOut(100, function () { jQuery("#flash").css("opacity", 1); }); }, debug: function (type, string) { jQuery("#status").html(type + ": " + string); }, onLoad: function () { var cams = webcam.getCameraList(); for(var i in cams) { jQuery("#cams").append("<li>" + cams[i] + "</li>"); } } }); function getPageSize() { var xScroll, yScroll; if (window.innerHeight && window.scrollMaxY) { xScroll = window.innerWidth + window.scrollMaxX; yScroll = window.innerHeight + window.scrollMaxY; } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac xScroll = document.body.scrollWidth; yScroll = document.body.scrollHeight; } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari xScroll = document.body.offsetWidth; yScroll = document.body.offsetHeight; } var windowWidth, windowHeight; if (self.innerHeight) { // all except Explorer if(document.documentElement.clientWidth){ windowWidth = document.documentElement.clientWidth; } else { windowWidth = self.innerWidth; } windowHeight = self.innerHeight; } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode windowWidth = document.documentElement.clientWidth; windowHeight = document.documentElement.clientHeight; } else if (document.body) { // other Explorers windowWidth = document.body.clientWidth; windowHeight = document.body.clientHeight; } // for small pages with total height less then height of the viewport if(yScroll < windowHeight){ pageHeight = windowHeight; } else { pageHeight = yScroll; } // for small pages with total width less then width of the viewport if(xScroll < windowWidth){ pageWidth = xScroll; } else { pageWidth = windowWidth; } return [pageWidth, pageHeight]; } window.addEventListener("load", function() { jQuery("body").append("<div id=\"flash\"></div>"); var canvas = document.getElementById("canvas"); if (canvas.getContext) { ctx = document.getElementById("canvas").getContext("2d"); ctx.clearRect(0, 0, 320, 240); var img = new Image(); img.src = "/images/rails.png"; img.onload = function() { ctx.drawImage(img, 129, 89); } image = ctx.getImageData(0, 0, 320, 240); } var pageSize = getPageSize(); jQuery("#flash").css({ height: pageSize[1] + "px" }); }, false); window.addEventListener("resize", function() { var pageSize = getPageSize(); jQuery("#flash").css({ height: pageSize[1] + "px" }); }, false); </script> 

Just make sure the jscam.swf "file specified in jquery.webcam.js is uploaded to the page correctly.

which you can define in routes.rb :

 resources :pictures do collection do get 'capture' post 'save_image' end end 

Here you can use this: https://github.com/blueimp/jQuery-File-Upload to download it using the Ajax form!

Let me know if you have any questions.

+5
source

mistakes.

Replace

 def save_image image = params[:canvas][:image] File.open("#{Rails.root}/public/path_you_want_to_image/image_name.png", 'wb') do |f| f.write(Base64.decode64(image)) end # Or use paperclip to save image for a model instead!! end 

on the

 def save_image image = params[:capture][:image] File.open("#{Rails.root}/public/path_you_want_to_image/image_name.png", 'wb') do |f| f.write(Base64.decode64(image)) end # Or use paperclip to save image for a model instead!! end 

and

 function capture_image(){ webcam.capture(); changeFilter(); void(0); var canvas = document.getElementById('canvas') var context = canvas.getContext("2d"); var img = canvas.toDataURL("image/png"); var item_image = img.replace(/^data:image\/(png|jpg);base64,/, "") ; document.getElementById('capture_images').innerHTML="<input id=\"capture_image\" type=\"hidden\" value=\""+capture_image+"\" name=\"capture[image]\">";} 

to

 function capture_image(){ webcam.capture(); changeFilter(); void(0); var canvas = document.getElementById('canvas') var context = canvas.getContext("2d"); var img = canvas.toDataURL("image/png"); var item_image = img.replace(/^data:image\/(png|jpg);base64,/, "") ; document.getElementById('capture_images').innerHTML="<input id='capture_image' type='hidden' value=\'"+item_image+"\' name='capture[image]'>";} 

After that, everything works fine.

PS. If you received: "capture_image () is not fn", change the name fn to: "capture_images ()", do not forget the name of the change in the onClick event

0
source

Source: https://habr.com/ru/post/914090/


All Articles