Beefy Boxes and Bandwidth Generously Provided by pair Networks Joe
There's more than one way to do things.
 
PerlMonks

Feeding video data to Imager

by saintmike (Vicar)
 | Log in | Create a new user | The Monastery Gates | Super Search | 
 | Seekers of Perl Wisdom | Meditations | PerlMonks Discussion | 
 | Obfuscation | Reviews | Cool Uses For Perl | Perl News | Q&A | Tutorials | 
 | Poetry | Recent Threads | Newest Nodes | Donate | What's New | 

on Mar 26, 2006 at 19:35 UTC ( #539316=perlquestion: print w/ replies, xml ) Need Help??
saintmike has asked for the wisdom of the Perl Monks concerning the following question:

When feeding RGB (or, more accurately, BGR) data from a video source to Imager, a wise perlmonk once suggested to use this trick:

use Imager; my $i = Imager->new(); $nfr = reverse $nfr; $i->read( type => "pnm", data => "P6\n$width $height\n255\n" . $nfr ); $i->flip(dir => "hv");
Is this still the best way to do it? It seems awkward that the mighty Imager wouldn't allow feeding it RGB data directly.

Comment on Feeding video data to Imager
Download Code
Re: Feeding video data to Imager
by tonyc (Monk) on Mar 27, 2006 at 00:01 UTC

    There's a few ways you could do it:

    • format the data as PPM as above, or perhaps raw would be better.
    • use the setscanline() method to write data a scanline at a time to the image. Unfortunately this expects data in a particular format, so you'll still need to adjust the data a bit.
    • # untested my $im = Imager->new(xsize=>$width, ysize=>$height); my $per_line = $width * 4; # adjust the data to the format setscanline() takes $nfr =~ s/(.)(.)(.)/$3$2$1\xFF/gs; # paint it for my $y (0..$height-1) { $im->setscanline(y=>$y, pixels => substr($nfr, $y * per_line, $per_line)); }
    • if performance is an issue you could use Inline::C or an XS module to reformat the data and draw it using i_plin() at the C level. Here's some Inline C code to do the job:
    • use Imager 0.48; # this assumes you've created an image of the right # size first. # if you call it with too large an image for the data # supplied then it will crash use Inline C => <<'EOS' => WITH => 'Imager'; void capture2image(Imager::ImgRaw out, unsigned char *data) { i_color *line_buf = mymalloc(sizeof(i_color) * out->xsize); i_color *pixelp; int x, y; for (y = 0; y < out->ysize; ++y) { pixelp = line_buf; for (x = 0; x < out->xsize; ++x) { pixelp->rgba.b = *data++; pixelp->rgba.g = *data++; pixelp->rgba.r = *data++; ++pixelp; } i_plin(out, 0, out->xsize, y, line_buf); } myfree(line_buf); } EOS

    Perhaps Imager needs a more general data to image method, but I haven't had much feedback on setscanline() and friends yet.

    Edit: added the Inline C code, hard to test without video capture data though.

[reply]
[d/l]
[select]
Re: Feeding video data to Imager
by zentara (Chancellor) on Mar 27, 2006 at 12:37 UTC
    Is this still the best way to do it? It seems awkward that the mighty Imager wouldn't allow feeding it RGB data directly.

    I chose to do it that way, because I thought it was faster than the direct way which Imager allows, which is matrix transformation. Read "perldoc Imager::Transformations, where the following matrix method is shown

    # Swap red/green channel $new = $img->convert(matrix=>[ [ 0, 1, 0 ], [ 1, 0, 0 ], [ 0, 0, 1 ] ]);
    but, I think you will find that reversing is faster, although it will only work for swapping R and B, plus you need to invert it afterwards. But let us know, if you find otherwise.

    I'm not really a human, but I play one on earth. flash japh
[reply]
[d/l]

Back to Seekers of Perl Wisdom


Login:
Password
remember me
What's my password?
Create A New User

Node Status
node history
Node Type: perlquestion [id://539316]
Approved by Corion
help
Community Ads
Chatterbox
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users
Others about the Monastery: (15)
BrowserUk
GrandFather
borisz
jdporter
holli
atcroft
Khen1950fx
herveus
thezip
Eyck
ssandv
perlsyntax
gnosti
wanradt
Gri
As of 2009-11-21 04:28 GMT
Sections
The Monastery Gates
Seekers of Perl Wisdom
Meditations
PerlMonks Discussion
Categorized Q&A
Tutorials
Obfuscated Code
Perl Poetry
Cool Uses for Perl
Perl News
Information
PerlMonks FAQ
Guide to the Monastery
What's New at PerlMonks
Voting/Experience System
Tutorials
Reviews
Library
Perl FAQs
Other Info Sources
Find Nodes
Nodes You Wrote
Super Search
List Nodes By Users
Newest Nodes
Recently Active Threads
Selected Best Nodes
Best Nodes
Worst Nodes
Saints in our Book
Leftovers
The St. Larry Wall Shrine
Offering Plate
Awards
Craft
Snippets Section
Code Catacombs
Quests
Editor Requests
Buy PerlMonks Gear
PerlMonks Merchandise
Planet Perl
Perlsphere
Use Perl
Perl.com
Perl 5 Wiki
Perl Jobs
Perl Mongers
Perl Directory
Perl documentation
CPAN
Random Node
Voting Booth

Future historians will find that the material characteristic of the current era is...

Aluminium
Plastic
Oil
Water
Carbon dioxide
Copper
Iron
Silicon
Salt
Uranium
Hydrogen
Other

Results (726 votes), past polls