Graphics-HotMap
view release on metacpan or search on metacpan
lib/Graphics/HotMap.pm view on Meta::CPAN
textSize => 8,
textColor => 'magenta',
},
zoneA => {
layerName => '40_anotherLayer',
coordonates => [0,10,1,12],
border => 1,
text => 'black',
textSize => 8,
textColor => 'white',
},
zoneB => {
layerName => '40_anotherLayer',
coordonates => [1,10,2,12],
border => 1,
text => 'blue',
textSize => 8,
textColor => 'white',
},
zoneC => {
layerName => '40_anotherLayer',
coordonates => [2,10,3,12],
border => 1,
text => 'green',
textSize => 8,
textColor => 'white',
},
zoneD => {
layerName => '40_anotherLayer',
coordonates => [3,10,4,12],
border => 1,
text => 'cyan',
textSize => 8,
textColor => 'white',
},
},
points => {
'30_anotherLayer' => [
[8,5,46],
[10,9,22],
],
'10_back' => [
[13,1,50],
],
'40_anotherLayer' => [
[0,10,1],
[1,10,2],
[2,10,3],
[3,10,4],
],
},
);
# ..., and import/add it
$hotMap->addConfs(\%other);
# Run the interpolation and generate and image
$hotMap->genImage;
# Save the image a a PNG file
$hotMap->genImagePng('MyTest.png');
# print the text representation of the map
print $hotMap->toString('floor') if $hotMap->scale < 3;
=head1 DESCRIPTION
Generate thermographic images from a few know points. Others values are interpolated. Graphics::HotMap use PDL to work on matrix.
PDL can compute very very large matrix in a few seconds.
See L<http://kumy.org/HotMap/HotMap.png>
=head2 FUNCTIONS
=over 4
=cut
use Data::Dumper;
use Image::Magick;
use Math::Gradient qw(multi_array_gradient);
use PDL;
use PDL::NiceSlice;
use PDL::IO::Pic;
use POSIX qw(strftime);
use File::Temp qw/ :POSIX /;
use File::Temp qw/ tempfile tempdir /;
use constant {
PALETTE_SLICE => 35,
};
our $VERSION = '0.0001';
=item new(<HASH>)
=for ref
Construct and return a new HotMap Object;
=for usage
Graphics::HotMap->new(
outfileGif => <File path>, # file to write GIF
outfilePng => <File path>, # file to write PNG
legend => [0|1], # activate lengend
legendNbGrad => <number>, # Number a graduation
cross => <bool>, # activate crossing of known values
crossValues => <bool>, # activate values printing whith cross
minValue => <number>, # minimum value
maxValue => <number>, # maximum value
font => <path to font file>,
fontSize => <number>, # font size
scale => <number>, # scale values and coordonates
sizeX => <number>, # X size
sizeY => <number>, # Y size
);
=for exemple
my $hotMap = Graphics::HotMap->new(
sizeX => 10,
sizeY => 10,
minValue => 1,
maxvalue => 50,
);
=cut
sub new {
my ($class, %params) = (@_);
my $self={};
$self->{_outfileGif} = $params{outfileGif} || undef;
$self->{_outfilePng} = $params{outfilePng} || undef;
$self->{_legend} = $params{legend} || 0;
$self->{_legendNbGrad} = $params{legendNbGrad} || 7;
$self->{_crossMark} = $params{cross} || 0;
$self->{_crossMarkTemp}= $params{crossTemp} || 0;
#$self->{_minValue} = $params{minValue} || 0;
#$self->{_maxValue} = $params{maxValue} || 70;
$self->{_font} = $params{font} || '/usr/share/fonts/truetype/freefont/FreeSans.ttf';
$self->{_fontSize} = $params{fontSize} || 15;
$self->{_text} = ();
$self->{_horodatage} = $params{horodatage} || [0, 0, 0];
$self->{_scale} = $params{echelle} || 1;
$self->{_verbose} = $params{verbose} || 0;
$self->{_mapSize}{x} = $params{sizeX} || 30;
$self->{_mapSize}{y} = $params{sizeY} || 20;
$self->{_knownPoints} = {};
$self->{_mapPoints} = PDL->zeroes(1);
bless $self, $class;
#$self->gradient(20, ([0,0,255],[0,255,255],[0,255,0],[255,255,0],[255,0,0]));
return $self;
}
=item initKnownPoints()
=for ref
Reset all know points.
=cut
sub initKnownPoints {
my $self = shift;
$self->{_knownPoints} = {};
}
=item mapSize(<HASH>)
=for ref
Set or Return mapSize
=for exemple
$hotMap->mapSize({sizeX => 15, sizeY => 15}); # Set map size
@size = $hotMap->mapSize; # Return the actual map size
=cut
sub mapSize {
my $self = shift;
my ($dimentions) = @_;
if (defined $dimentions) {
die ("mapSize: You must set sizeX and sizeY.",$/)
unless (defined $dimentions->{sizeX} && defined $dimentions->{sizeY});
$self->{_mapSize}{x} = ($dimentions->{sizeX} ) * $self->{_scale};
$self->{_mapSize}{y} = ($dimentions->{sizeY} ) * $self->{_scale};
$self->{_mapPoints} = PDL->zeroes($self->{_mapSize}{x}, $self->{_mapSize}{y});
lib/Graphics/HotMap.pm view on Meta::CPAN
# generate gradient interpolation
$self->_pdlDegrad($knownPointsSlice, $mapPointsSlice, $sliceColors, $gradientName);
# draw walls
if (defined $zoneHash->{border}) {
$mapPointsSlice->(0) .= $zoneHash->{border};
$mapPointsSlice->(-1) .= $zoneHash->{border};
$mapPointsSlice->(:,0) .= $zoneHash->{border};
$mapPointsSlice->(:,-1) .= $zoneHash->{border};
}
#$mapPointsSlice = byte($mapPointsSlice);
}
=for comment
Fetch zone
=cut
sub _genDegrad {
my $self = shift;
$self->_genGradient;
foreach my $layerName (sort keys %{$self->{_zones}}) {
foreach my $zoneName (sort keys %{$self->{_zones}{$layerName}}) {
$self->_genDegradZone($layerName, $self->{_zones}{$layerName}{$zoneName});
}
}
}
=item genImage()
=for ref
Calculate the interpolation of all Zones.
=cut
sub genImage {
my $self = shift;
$self->{_mapPoints} = PDL->zeroes($self->{_mapSize}{x}, $self->{_mapSize}{y});
$self->_genDegrad;
$self->_genPicture;
}
=for comment
This function will write image to disk.
=cut
sub _saveImg {
my $self = shift;
my ($outfile, $im) = @_;
print $im->Write(filename=>$outfile); #, compression=>'JPEG', type => 'Palette');
}
=item genImagePng()
=for ref
Write a PNG image from the interpolated table.
=for exemple
$hotMap->genImagePng('<path_to_png'>);
=cut
sub genImagePng {
my $self = shift;
my $fileName = shift || $self->{_outfilePng} || die "No output PNG specified";
$self->_saveImg($fileName,$self->{_im});
return {
width => $self->{_im}->Get('width'),
height => $self->{_im}->Get('height'),
filesize => $self->{_im}->Get('filesize'),
mime => $self->{_im}->Get('mime'),
image => $self->{_im},
};
}
=item genImageGif()
=for ref
Add a GIF image to the annimation from the interpolated table.
=for exemple
$hotMap->genImageGif('<path_to_gif'>);
=cut
sub genImageGif {
my $self = shift;
my $fileName = shift || $self->{_outfileGif} || die "No output GIF specified";
my $image = shift;
my $im = $self->{_im};
unless (defined $image) {
$image = new Image::Magick(size => "$self->{_mapSize}{x}x$self->{_mapSize}{y}");
$image->Read($fileName);
}
$image->Set(magick=>'GIF', loop=> 100);
$im->Set(magick=>'GIF', delay=>100);
push (@$image, $im);
$self->_saveImg($fileName, $image);
return {
width => $image->Get('width'),
height => $image->Get('height'),
filesize => $image->Get('filesize'),
mime => $image->Get('mime'),
image => $image,
};
}
=back
=head1 SEE ALSO
PDL
Math::Gradient
=head1 AUTHOR
Mathieu Alorent (cpan@kumy.net)
=cut
1;
( run in 2.879 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )