Webcam picture straight to file attachment

前端 未结 2 1517
Happy的楠姐
Happy的楠姐 2020-12-30 13:56

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


Now I figure

相关标签:
2条回答
  • 2020-12-30 14:47

    I'd used this: http://www.xarg.org/project/jquery-webcam-plugin/ in my rails application for capturing an image from a webcam. You can download this jQuery-webcam here: https://github.com/infusion/jQuery-webcam

    Here is a roughly done 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>
    

    views/pictures/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 that, "jscam.swf" file referenced in jquery.webcam.js is loaded on page properly.

    routes you can define in your routes.rb are:

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

    From here, you can then use this: https://github.com/blueimp/jQuery-File-Upload for uploading it using an Ajax form submission!!

    Do let me know if you have any questions.

    0 讨论(0)
  • 2020-12-30 14:56

    Errors.

    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
    

    by 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 this, all work fine.

    PS. If you got: "capture_image() is not a f-n", change f-n name to: "capture_images()" don't forget change name on the onClick event

    0 讨论(0)
提交回复
热议问题