Capture Webcam's Image with Ruby

Capture webcam's image with Ruby

This looks good http://www.wedesoft.demon.co.uk/hornetseye-api/files/HornetsEye-txt.html although I don't have any experience using it.

Grabbing snapshots from webcams in ruby

I'm the developer of Hornetseye. You can capture images with the V4L2-interface of HornetsEye as follows.

require 'rubygems'
require 'hornetseye_v4l2'
require 'hornetseye_xorg'
require 'hornetseye_rmagick'
include Hornetseye
input = V4L2Input.new '/dev/video0'
img = X11Display.show { input.read }
img.to_ubytergb.save_ubytergb 'test.png'

Currently supported colourspaces are UYVY, YUYV, YUV420, GREY, RGB24. Note that other colourspaces such as MJPEG are not supported at the moment.

Ruby on Rails capture webcam video and audio

Have you heard about navigator.getUserMedia()? That could the trick. More info: http://www.html5rocks.com/en/tutorials/getusermedia/intro/

They talk about it in the Mobile Web Development course in Udacity (lesson 10).
https://www.youtube.com/watch?v=j6mzYt5fJpg

Can you use a webcam with ruby-opencv in realtime?

OpenCV has Python bindings which will call native C++ code under the hood. They also have many tutorials on how to use the Python API. A basic example of opening a video feed can be found here, and a longer list of tutorials is here. I highly recommend looking through them if you are interested in doing much work with OpenCV.

A brief summary of the first tutorial:

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

while(True):
# Capture frame-by-frame
ret, frame = cap.read()

# Do image processing here, using frame

# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

use flash capture webcam image?

This sounds like a good candidate for Thibault Imbert's AS3 GIF Animation Encoding Class.
I've used it about 2 years ago for a project at University. You can check it out here.
In my opinion you would have 3 steps:

//1.Create a Camera object

//this code comes from the LiveDocs
var camera:Camera = Camera.getCamera();
var video:Video;
if (camera != null) {
video = new Video(camera.width * 2, camera.height * 2);
video.attachCamera(camera);
addChild(video);
} else {
trace("You need a camera.");
}

//2. Take one or more 'screenshots' using BitmapData

var screenshot:BitmapData = new BitmapData(video.width,video.height,false,0x009900);
screenshot.draw(video);
//you would probably save more of these in an array called screenshots maybe

//3. Create a GIFEncoder and send it to the server:

//assuming screenshots is an array of BitmapData objects previously saved
var animationEncoder:GIFEncoder = new GIFEncoder();
animationEncoder.setRepeat(0);
animationEncoder.setDelay (150);
animationEncoder.start();
for(var i:int = 1 ; i < screenshots.length ; i++){
animationEncoder.addFrame(screenshots[i]);
}
animationEncoder.finish();
//save it on the server
var header:URLRequestHeader = new URLRequestHeader ("Content-type", "application/octet-stream");//binary header
var gifRequest:URLRequest = new URLRequest ('http://yourServer/writeGIF.php?name=myFile.gif&method=download');
gifRequest.requestHeaders.push (header);
gifRequest.method = URLRequestMethod.POST;
gifRequest.data = animationEncoder.stream;
sendToURL(gifRequest);

//Obviously you would have listeners to check if everything was ok, and when the operation //is complete.

//The PHP code would be something simple as this

<?php

$method = $_GET['method'];
$name = $_GET['name'];

if ( isset ( $GLOBALS["HTTP_RAW_POST_DATA"] )) {

// get bytearray
$gif = $GLOBALS["HTTP_RAW_POST_DATA"];

// add headers for download dialog-box
header('Content-Type: image/gif');
header('Content-Length: '.strlen($gif ));
header('Content-disposition:'.$method.'; filename="'.$name.'".gif');

echo $gif ;

} else echo 'An error occured.';

?>

That should be it.

Make sure you check out Thibault Imbert's AS3 GIF Animation Encoding Class and this Web-Cam-Stop-Motion fun app :)
Lee Felarca's SimpleFlvWriter is worth looking at as well, depending on your needs.

Webcam picture straight to file attachment

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.



Related Topics



Leave a reply



Submit