摄像头图片直接到文件附件 [英] Webcam picture straight to file attachment

查看:146
本文介绍了摄像头图片直接到文件附件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个表单,用这种形式用户可以上传一张图片。作为替代方案,我希望他们能够拍照并上传照片。现在,我认为当用户拍摄某种照片时闪存摄像头界面,该图片需要存储在某种中介内存,而用户完成他/她的形式。

有没有办法解决这个问题?什么是最好的解决方案?



我认为只有两个选项。 (b)我持有临时照片,然后在表单提交后再次接受;(b)用户拍照,它被下载到他们的本地机器,他们必须选择它作为一个文件被提交。


这些解决方案都不是对我来说真的很满意,所以我想知道是否有更好的方法来做到这一点。

编辑:没有真正相关的,我正在使用Paperclip的文件附件的Rails应用程序。此外,我更喜欢使用jQuery ...



也只是从有经验的UI Web开发人员的一般意见将是很好的..

解决方案

我曾经使用过: http://www.xarg.org/project/jquery-webcam-plugin/ 在我的Rails应用程序中捕捉网络摄像头的图像。你可以在这里下载这个jQuery-webcam: https://github.com/infusion/jQuery-webcam



这是一个大致完成的实现,对于乱码代码抱歉:

  class PicturesController< ApplicationController 
require'base64'
def capture
#做某事
render:layout => webcam
end
$ b $ 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
#或者使用回形针来保存模型的图像!
end
end



views / layouts / webcam.html。 erb


 <!DOCTYPE html> 
< html>
< head>
< title>应用程式名称< / title>
<%= stylesheet_link_tag:all%>
<%= javascript_include_tag:defaults%>
<%= javascript_include_taghttp://www.google-analytics.com/ga.js\"%>
<%= javascript_include_taghttp://code.jquery.com/jquery-1.4.2.min.js\"%>
<%= javascript_include_tagjquery.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>在这里捕捉图片!< / 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_imagetype =hiddenvalue =name =capture [image]>< / div>
<%= submit_tagCapture Image,:onClick =>javascript:capture_image();%>
<%end%>
<%= link_to返回,root_path%>
< p>
< canvas id =canvaswidth =320height =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;



函数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 = \ 捕获[图像] \ >中;

$ b $ 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,
模式:callback,
swffile:/javascripts/jscam_canvas_only.swf,

onTick:函数(保留){

if(0 ==保留){
jQuery(#status)。text(Cheese!);
} else {
jQuery(#status)。text(remain +seconds剩余...);
}
},

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); (var i = 0; i <320; i ++){
var tmp = parseInt(col [i]);



/ *在这里复制了一些xcolor方法比调用xcolor里面的所有方法更快,并且不需要每个请求都提供完整的库* /

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的; ((r + = 32)<0)r = 0;
; ((g + = 32)<0)g = 0;如果((b + = 32)<0)b = 0,则
;
} else if(id == 6){
r =(tmp>> 16)& 0xFF的;
g =(tmp>> 8)& 0xFF的;
b = tmp& 0xFF的; ((r- = 32)<0)r = 0;
; ((g- = 32)<0)g = 0; ((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;

$ b $
$ b onCapture:function(){
webcam.save('/ product_capture');

jQuery(#flash)。css(display,block);
jQuery(#flash)。fadeOut(100,function(){
jQuery(#flash).css(opacity,1);
});


$ b 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>);
}
}
});

函数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){//全部除了资源管理器Mac
xScroll = document.body.scrollWidth;
yScroll = document.body.scrollHeight;
} else {// Explorer Mac ...也可以在Explorer 6中使用Strict,Mozilla和Safari
xScroll = document.body.offsetWidth;
yScroll = document.body.offsetHeight;
}

var windowWidth,windowHeight;

if(self.innerHeight){//除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){//其他Explorers
windowWidth = document.body.clientWidth;
windowHeight = document.body.clientHeight;
}

//对于总高度小于视口高度的小页面
if(yScroll< windowHeight){
pageHeight = windowHeight;
} else {
pageHeight = yScroll;
}

//对于总宽度小于视口宽度的小页面
if(xScroll< windowWidth){
pageWidth = xScroll;
} else {
pageWidth = windowWidth;
}

return [pageWidth,pageHeight];

$ b $ window.addEventListener(load,function(){

jQuery(body)。append(< div id = \ (canvas);

if(canvas.getContext){(canvas);

var canvas = document.getElementById
ctx = document.getElementById(canvas)。getContext(2d);
ctx.clearRect(0,0,320,240);

var img =新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(){
$ b $ var pageSize = getPageSize();
jQuery(#flash)。css({ height:pageSize [1] +px});

},false);
< / script>

只要确保在jquery中引用了 jscam.swf 文件.webcam.js正确加载在页面上。



可以在 routes.rb 中定义路线:

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

从这里开始,您可以使用这个: https://github.com/blueimp/jQuery-File-Upload 以上传Ajax表单提交!!



如果您有任何问题,请告诉我。


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 that when a user takes a picture with some sort of flash webcam interface, that picture needs to be stored in some sort of intermediary memory while the user completes his/her form.

Is there a way around this? What's the best solution?

I figure there are only really two options.

Either (a) I hold the temporary photo and then accept it again once the form is submitted or (b) the user takes a picture, it's downloaded onto their local machine, and they have to choose it as a file to be submitted again.

Neither of these solutions are really satisfactory to me, so I wanted to know if there's any better way to do this.

Edit: As an added bonus, although it's not really relevant, I'm making a Rails app with Paperclip for file attachments. Also, I prefer to work with jQuery...

Also just general opinions from experienced UI web developers would be nice..

解决方案

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.

这篇关于摄像头图片直接到文件附件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆