http://www.perlmonks.org?node_id=450602


in reply to Cross platform webcam-capturing?

I don't know about windows, but this may help you with your V4l on linux. Notice, if your webcam has a tuner, you have to watch which channel you use. Your composite will be on channel(1) if your card has a tv tuner, otherwise channel(0). Also notice the need to convert from BGR to RGB.
#!/usr/bin/perl use warnings; use strict; use Video::Capture::V4l; use Imager; use Tk; use Tk::JPEG; use MIME::Base64; my $timestamp; my $temp = ''; sub grab_one { $temp = ''; $timestamp = scalar(localtime); $timestamp =~ tr/ /_/; $| = 1; my $grab = new Video::Capture::V4l or die "Unable to open Videodevice: $!"; # the following initializes the camera for NTSC my $channel = $grab->channel(1); #1 is composite 0 is for tuner my $tuner = $grab->tuner(0); $tuner->mode(1); $channel->norm(1); $tuner->set; $channel->set; my $frame = 0; my $fr = $grab->capture( $frame, 320, 240 ); my $count = 0; for ( 0 .. 1 ) { my $nfr = $grab->capture( 1 - $frame, 320, 240 ); $grab->sync($frame) or die "unable to sync"; unless ( $count == 0 ) { # save $fr now, as it contains the raw BGR data $temp = ''; open( JP, '>', \$temp ) or die $!; print JP "P6\n320 240\n255\n"; #header $nfr = reverse $nfr; print JP $nfr; close JP; my $img = Imager->new(); $img->read( data => $temp, type => 'pnm' ) or warn $img->errstr(); $img->flip( dir => "hv" ); $img->write( data => \$temp, type => 'jpeg' ) or warn $img->errstr; } $count++; $frame = 1 - $frame; $fr = $nfr; } } grab_one(); my $mw = MainWindow->new(); my $image = $mw->Photo( -data => encode_base64($temp) ); $mw->Label( -image => $image )->pack( -expand => 1, -fill => 'both' ); my $label = $mw->Label( -text => $timestamp )->pack( -side => 'top', -padx => 3 +); my $center = $mw->Frame->pack( -anchor => 'center' ); $center->Button( -text => 'Quit', -command => [ destroy => $mw ] ) ->pack( -side => 'left', -padx => 3 ); $center->Button( -text => 'Update', -command => \&update ) ->pack( -side => 'left', -padx => 3 ); $center->Button( -text => 'Save', -command => \&save_it ) ->pack( -side => 'left', -padx => 3 ); MainLoop; sub save_it { open( JP, "> $timestamp.jpg" ) or die $!; print JP $temp; close JP; $label->configure( -text => "$timestamp.jpg SAVED" ); $label->update; } sub update { grab_one(); $label->configure( -text => "$timestamp" ); $label->update; $image->configure( -data => encode_base64($temp) ); $image->update; $mw->update; }

I'm not really a human, but I play one on earth. flash japh

Replies are listed 'Best First'.
Re^2: Cross platform webcam-capturing?
by schweini (Friar) on Apr 22, 2005 at 22:46 UTC
    thanks - even though maybe i should've made clear that i'm trying to access a cheapo-USB-webcam, and was kind of looking for a solution along the lines of:
    use Device::Webcam; # pity this on doesn't exist my $wc = Device::Webcam->init('/dev/video/0', '800x600'); my $jpeg = $wc->capture( format => 'jpeg' );
    hmmm....if i'd actually start a Device::Webcam, that does nothing more than wrap around vidcat on linux (v4l) systems, would that be worth putting on CPAN?
      Sure, put it on CPAN, if you have tested it, and are sure it works with all of the different possible setups. Otherwise, just post it here in the snippets, or code sections.

      I'm not really a human, but I play one on earth. flash japh