I have a Perl script that generates a display window
containing various informational text in varying
colors all on a black background. What I need to do
is to be able to "screen capture" this display and
save it as an image file (JPEG, BMP, whatever).
Various suggestions on the web talk about using
Tk::WinPhoto, but I'm not using X (I'm on Windows XP)
and WinPhoto doesn't exist in my Tk directory.
Attempts to even try it using the following snippet
(with Tk::Photo and Tk::JPEG)
$image = $mw->Photo(-format => 'Window',
-data => oct($JTADisplay->id));
$filename = 'myimage.jpg';
$image->write($filename, -format => 'JPEG');
gives me the following error (understandably):
Tk::Error: image format "Window" is not supported at C:/Perl/site/lib/Tk/Image.pm line 21.
So, if anybody can shed some light to this, I would be
most thankful. The following is another snippet of my
code if it helps:
$mw = MainWindow->new(-background => 'black');
$mw->geometry('+0+0');
$mw->title("My Display");
$f = $mw->Frame(-background => 'black')->pack;
$f->Label(-text => 'PROJECTION', -foreground => 'white',
-background => 'black')->
grid(-row => 1, -column => 1, -columnspan => 3, -sticky => 'w');
for ($i = 0; $i <= 5; $i++)
{
$f->Label(-text => $i, -foreground => 'white', -background => 'black')->
grid(-row => 1, -column => $i + 4, -sticky => 'nsew');
}
$advisoryLabel = $f->Label(-textvariable => \$advisory,
-foreground => $advisoryColor,
-background => 'black')->
grid(-row => 2, -column => 1, -columnspan => 3,
-sticky => 'w');
for ($i = 0; $i <= 5; $i++)
{
$JTALabel[$i] = $f->Label(-textvariable => \$JTA[$i + 1],
-foreground => $JTAColor[$i + 1],
-background => 'black')->
grid(-row => 2, -column => $i + 4,
-sticky => 'nsew');
}
$f->Label(-text => 'BREAKDOWN', -foreground => 'white',
-background => 'black')->grid(-row => 3, -column => 1,
-columnspan => 9, -sticky => 'nsew');
$f->Label(-text => 'ID', -foreground => 'white',
-background => 'black')->grid(-row => 4, -column => 1,
-sticky => 'w');
$f->Label(-text => 'TYPE', -foreground => 'white',
-background => 'black')->grid(-row => 4, -column => 2,
-sticky => 'w');
for ($i = 0; $i <= 5; $i++)
{
$f->Label(-text => $i, -foreground => 'white', -background => 'black')->
grid(-row => 4, -column => $i + 4, -sticky => 'nsew');
}
foreach $name (keys %Domes)
{
$domeIndex = $Domes{$name}{dome};
$fRow = ($domeIndex * 2) + 6;
$IDLabel[$domeIndex] = $f->Label(-text => $name,
-foreground => 'green', -background => 'black')->
grid(-row => $fRow, -column => 1, -sticky => 'w');
$TypeLabel[$domeIndex] = $f->Label(
-textvariable => \$Type[$domeIndex],
-foreground => 'green', -background => 'black')->
grid(-row => $fRow, -column => 2, -sticky => 'w');
$f->Label(-text => 'PA:', -foreground => 'white',
-background => 'black')->
grid(-row => $fRow, -column => 3, -sticky => 'w');
$f->Label(-text => 'RA:', -foreground => 'white',
-background => 'black')->
grid(-row => $fRow + 1, -column => 3, -sticky => 'w');
for ($i = 0; $i <= 5; $i++)
{
$JABLabel[$domeIndex][0][$i] = $f->Label(
-textvariable => \$JABText[$domeIndex][0][$i + 1],
-foreground => 'green', -background => 'black')->
grid(-row => $fRow, -column => $i + 4, -sticky => 'nsew');
$JABLabel[$domeIndex][1][$i] = $f->Label(
-textvariable => \$JABText[$domeIndex][1][$i + 1],
-foreground => 'green', -background => 'black')->
grid(-row => $fRow + 1, -column => $i + 4, -sticky => 'nsew');
}
}
# create the menus
$menuBar = $mw->Menu;
$mw->configure(-menu => $menuBar);
$file = $menuBar->cascade(-label => 'File', -tearoff => 0);
$file->command(-label => 'New', -command => \&newDemo);
$file->command(-label => 'Save Display', -command => \&saveDisplay);
$file->separator;
$file->command(-label => 'Quit', -command => \&closeWindow);
$action = $menuBar->cascade(-label => 'Scenario', -tearoff => 0);
$action->command(-label => 'Start Demo', -command => \&JTAMain);
$action->command(-label => 'Stop Demo', -command => sub {$stopDemo = 1});
MainLoop();
sub saveDisplay
{
$image = $mw->Photo(-format => 'Window',
-data => oct($JTADisplay->id));
$filename = 'myimage.jpg';
$image->write($filename, -format => 'JPEG');
}
Thanks in advance.
I tried adding the pragmas:
use strict; use warnings;at the top of the second code snippet (as well as the necessary library use Tk); not surprisingly, it fails to run.
You may want to consider supplying a complete code example, which will help us separate the problem you're having from the other problems currently in the code, such as textvariable references which don't exist (eg. advisory and $JTA), and other data which hasn't been included.
So, if you can post a program which runs as is, I'll be happy to try to give you an answer to your question.
liverpole, the following is an executable code that
will generate an example display of what I want to
save as an image file:
use Tk;
use Tk::Photo;
use Tk::JPEG;
$advisory = 'CAUTION';
$advisoryColor = 'yellow';
@JTA = ('Y','Y','Y','N','N','Y');
@JTAColor = ('green','green','green','yellow','yellow','green');
@IDColor = ('green','green','green','yellow','yellow','yellow','green',
'yellow','yellow','green');
@type = ('PAI','PAO','PAS','RAO','RAS','RAI','PAI','RAI','PAS','PAO');
for ($i = 0; $i < 10; $i++)
{
if ((($i >= 0) && ($i <= 2)) || ($i == 6) || ($i == 9))
{
@{$JABText[$i][0]} = ('Y','Y','Y','Y','Y','Y');
@{$JABColor[$i][0]} = ('green','green','green','green','green',
'green');
}
else
{
@{$JABText[$i][0]} = ('Y','Y','Y','N','N','Y');
@{$JABColor[$i][0]} = ('green','green','green','yellow','yellow',
'green');
}
@{$JABText[$i][1]} = ('Y','Y','Y','Y','Y','Y');
@{$JABColor[$i][1]} = ('green','green','green','green','green','green');
}
# create the GUI display
$mw = MainWindow->new(-background => 'black');
$mw->geometry('+0+0');
$mw->title("Info Display");
$f = $mw->Frame(-background => 'black')->pack;
$f->Label(-text => 'Advisory', -foreground => 'white',
-background => 'black')->
grid(-row => 1, -column => 1, -columnspan => 3, -sticky => 'w');
for ($i = 0; $i <= 5; $i++)
{
$f->Label(-text => $i, -foreground => 'white', -background => 'black')->
grid(-row => 1, -column => $i + 4, -sticky => 'nsew');
}
$advisoryLabel = $f->Label(-textvariable => \$advisory,
-foreground => $advisoryColor,
-background => 'black')->
grid(-row => 2, -column => 1, -columnspan => 3,
-sticky => 'w');
for ($i = 0; $i <= 5; $i++)
{
$JTALabel[$i] = $f->Label(-textvariable => \$JTA[$i],
-foreground => $JTAColor[$i],
-background => 'black')->
grid(-row => 2, -column => $i + 4,
-sticky => 'nsew');
}
$f->Label(-text => 'BREAKDOWN', -foreground => 'white',
-background => 'black')->grid(-row => 3, -column => 1,
-columnspan => 9, -sticky => 'nsew');
$f->Label(-text => 'ID', -foreground => 'white', -background => 'black')->
grid(-row => 4, -column => 1, -sticky => 'w');
$f->Label(-text => 'TYPE', -foreground => 'white', -background => 'black')->
grid(-row => 4, -column => 2, -sticky => 'w');
for ($i = 0; $i <= 5; $i++)
{
$f->Label(-text => $i, -foreground => 'white', -background => 'black')->
grid(-row => 4, -column => $i + 4, -sticky => 'nsew');
}
for ($i = 0; $i < 10; $i++)
{
$name = 'station'.$i;
$fRow = ($i * 2) + 6;
$IDLabel[$i] = $f->Label(-text => $name,
-foreground => $IDColor[$i], -background => 'black')->
grid(-row => $fRow, -column => 1, -sticky => 'w');
$typeLabel[$domeIndex] = $f->Label(-textvariable => \$type[$i],
-foreground => $IDColor[$i], -background => 'black')->
grid(-row => $fRow, -column => 2, -sticky => 'w');
$f->Label(-text => 'PA:', -foreground => 'white',
-background => 'black')->
grid(-row => $fRow, -column => 3, -sticky => 'w');
$f->Label(-text => 'RA:', -foreground => 'white',
-background => 'black')->
grid(-row => $fRow + 1, -column => 3, -sticky => 'w');
for ($j = 0; $j <= 5; $j++)
{
$JABLabel[$i][0][$j] = $f->Label(
-textvariable => \$JABText[$i][0][$j],
-foreground => $JABColor[$i][0][$j], -background => 'black')->
grid(-row => $fRow, -column => $j + 4, -sticky => 'nsew');
$JABLabel[$i][1][$i] = $f->Label(
-textvariable => \$JABText[$i][1][$j],
-foreground => $JABColor[$i][1][$j], -background => 'black')->
grid(-row => $fRow + 1, -column => $j + 4, -sticky => 'nsew');
}
}
# create the menus
$menuBar = $mw->Menu;
$mw->configure(-menu => $menuBar);
$file = $menuBar->cascade(-label => 'File', -tearoff => 0);
$file->command(-label => 'Save Display', -command => \&saveDisplay);
$file->separator;
$file->command(-label => 'Quit', -command => \&closeWindow);
MainLoop();
sub saveDisplay
{
$image = $mw->Photo(-format => 'Window', -data => oct($mw->id));
$filename = 'myimage.jpg';
$image->write($filename, -format => 'JPEG');
}
sub closeWindow
{
$mw->destroy;
}
Thanks again for trying to help me out
Zentara, I've seen many references to the Image Magick
that you've mentioned while surfing the net for this
solution. Maybe I should check this out. Thanks!
I've only used the Photo object before to create images in the GUI itself, so I went to Active State's website to find out what they support. According to their documentation for the Photo object:
The standard Tk distribution comes with handlers for XBM, XPM, BMP, JPEG, PNG and PPM/PGM formats, which are automatically registered on initialization.
I didn't see anything there about the Window format, or any kind of reference to doing a screen capture. Are you sure it's supposed to be a valid operation?
If it's a screen capture you need, would you consider doing it with a separate program? If so, you might want to try The Gimp, which is a very powerful freeware image editor that supports screenshots (single windows and desktop both), and runs great on Windows.
Did you get a solution already? If not, take a look at Win32::Screenshot. It has Image::Magick as a dependancy, but it seems to cover most possibilities.
perlmonks.org content © perlmonks.org and Anonymous Monk, baklobsters, BrowserUk, liverpole, zentara
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03