#!/usr/bin/perl -w # # use strict; use Image::Magick; my $usage = "Usage: $0 \n"; my $infile = shift or die $usage; my $outfile = shift or die $usage; my $font; #my %matrix = &readData($infile); my @dataArray = &readData($infile); my $matrixSize = 1000; # # Determine the data size. # my $dataSize = 0; foreach my $rec (@dataArray) { $dataSize = $rec->{X} if ($rec->{X} > $dataSize); $dataSize = $rec->{Y} if ($rec->{Y} > $dataSize); } my $scale = int($matrixSize / $dataSize); $matrixSize = $dataSize * $scale; $matrixSize = $dataSize if ($dataSize > $matrixSize); my $xOrig = int($matrixSize/5.5); my $yOrig = $xOrig; my $cmapAllowance = $xOrig + int(2.2*$scale); #print("Data size: $dataSize\n"); #print("Image size: $matrixSize\n"); #print("Scale: $scale\n"); #print("Drawing...\n"); my $image = &initGraphics($matrixSize+$xOrig+$cmapAllowance,$matrixSize+$yOrig); # # Draw the matrix. # foreach my $rec (@dataArray) { my $hexColor = &selectColor($rec->{VALUE}); print("$rec->{X}-1, $rec->{Y}-1\n") if ($rec->{Y} == 616); &drawSquare($image, $xOrig, $yOrig, $rec->{X}-1, $rec->{Y}-1, $hexColor); &drawSquare($image, $xOrig, $yOrig, $rec->{Y}-1, $rec->{X}-1, $hexColor); } # # Draw the leading diagonal. # for (my $i=0; $i<=$dataSize; $i++) { &drawSquare($image, $xOrig, $yOrig, $i, $i, '#ff0000'); } # # Draw the axis labels. # my $i = 0.5; foreach my $label (&getNames($dataSize, @dataArray)) { my $x = $xOrig + $scale*$i; my $y = $yOrig + $scale*$i++; &drawLabel($image, $label, $x, 'X'); &drawLabel($image, $label, $y, 'Y'); } # # Symbolic names # #&drawLines($image, $matrixSize, 11); #&drawLines($image, $matrixSize, 21); #&drawLines($image, $matrixSize, 25); #&drawLines($image, $matrixSize, 29); # # Draw the colormap key. # &drawColormapKey($image, $xOrig+$matrixSize+$scale, $yOrig); # # Save the file. # $image->Crop('0x0'); if ($outfile =~ /\.png$/) { #my $r = $image->Write(filename=>"png8:$outfile"); my $r = $image->Write(filename=>$outfile); warn $r if $r; } else { $image->Write(filename=>$outfile); } undef $image; sub readData { my ($infile) = @_; #print("Reading...\n"); open(IN, $infile) or die "Cannot open $infile\n"; my @dataArray = (); while () { chomp; my ($xname, $x, $yname, $y, $value1) = split(/\s+/); my $rec = { XNAME => $xname, YNAME => $yname, X => $x, Y => $y, VALUE => $value1, }; push(@dataArray, $rec); } close(IN); return @dataArray; } sub getNames { my ($dataSize, @dataArray) = @_; my @names = (); foreach my $rec (@dataArray) { $names[0] = $rec->{XNAME} if ($rec->{X} == 1); $names[$rec->{Y}-1] = $rec->{YNAME}; last if ($rec->{X} != 1); # bail out } return @names; } sub initGraphics { my ($width, $height) = @_; my $image = Image::Magick->new(); $image->Set(size=>"${width}x${height}"); $image->ReadImage('xc:#ffffff'); if (-r 'C:\Winnt\Fonts\Arial.ttf') { $font = 'C:\Winnt\Fonts\Arial.ttf'; } elsif (-r '/home/wes/proj/perl/arial.ttf') { $font = '/home/wes/proj/perl/arial.ttf'; } else { die "Cannot find a font file.\n"; } return $image; } sub drawSquare { my ($image, $x0, $y0, $x, $y, $hexColor) = @_; my $x1 = $x0 + $x * $scale; my $y1 = $y0 + $y * $scale; my $x2 = $x1 + $scale - 1; my $y2 = $y1 + $scale - 1; $image->Draw(primitive=>'rectangle', fill=>$hexColor, stroke=>'#111111', points=>"$x1,$y1 $x2,$y2"); #$image->Draw(primitive=>'rectangle', fill=>$hexColor, stroke=>$hexColor, points=>"$x1,$y1 $x2,$y2"); } sub drawLabel { my ($image, $text, $pos, $xory) = @_; my $pointsize = int(0.7*$scale); if ($xory eq 'Y') { my $x = $matrixSize + $cmapAllowance; # from right side of image $pos += 0.5*$pointsize; $image->Annotate(text=>$text, font=>$font, pointsize=>$pointsize, fill=>'#000000', x=>$x, y=>$pos, gravity=>'NorthEast'); } else { # X $pos += 0.5*$pointsize; $image->Annotate(text=>$text, font=>$font, pointsize=>$pointsize, fill=>'#000000', x=>$pos, y=>$yOrig, rotate=>270); } return; } sub selectColor { my ($value) = @_; my $maxVal = 255; my $gray = 0; my $hexColor; if ($gray) { my $gray = int(0.5*($value + 1)*$maxVal); my $hex = sprintf("%x", $gray); # lower case a-f $hexColor = "#$hex$hex$hex"; } else { # if ($value <= -0.85) { $hexColor = '#0000ff'; } # elsif ($value <= -0.80) { $hexColor = '#3399ff'; } # elsif ($value <= -0.70) { $hexColor = '#66ccff'; } # elsif ($value <= -0.08) { $hexColor = '#ffffff'; } # elsif ($value <= -0.03) { $hexColor = '#ffffff'; } # elsif ($value <= 0.03) { $hexColor = '#ffffff'; } # elsif ($value <= 0.08) { $hexColor = '#ffffff'; } # elsif ($value <= 0.70) { $hexColor = '#ffffff'; } # elsif ($value <= 0.80) { $hexColor = '#ff66cc'; } # elsif ($value <= 0.85) { $hexColor = '#ff6666'; } if ($value <= -0.8) { $hexColor = '#0000ff'; } elsif ($value <= -0.6) { $hexColor = '#3399ff'; } elsif ($value <= -0.4) { $hexColor = '#66ccff'; } elsif ($value <= -0.2) { $hexColor = '#99ccff'; } elsif ($value <= -0.05) { $hexColor = '#ccccff'; } elsif ($value <= 0.05) { $hexColor = '#ffffff'; } elsif ($value <= 0.2) { $hexColor = '#ffccff'; } elsif ($value <= 0.4) { $hexColor = '#ff99ff'; } elsif ($value <= 0.6) { $hexColor = '#ff66cc'; } elsif ($value <= 0.8) { $hexColor = '#ff6666'; } else { $hexColor = '#ff0000'; } } return $hexColor; } sub drawColormapKey { my ($image, $x0, $y0) = @_; my $pointsize = int(0.4*$scale); my $x = $x0 + $scale + 5; my $i = 0; for my $value qw(1.00 0.80 0.60 0.40 0.20 0.05 -0.05 -0.20 -0.40 -0.60 -0.80) { my $hexColor = &selectColor($value-0.01); &drawSquare($image, $x0, $y0, 0, $i, $hexColor); my $y = $y0 + $scale*$i++ + int(0.5*$pointsize); $image->Annotate(text=>$value, font=>$font, pointsize=>$pointsize, fill=>'#000000', x=>$x, y=>$y); } my $y = $y0 + $scale*$i++ + int(0.5*$pointsize); $image->Annotate(text=>'1.0', font=>$font, pointsize=>$pointsize, fill=>'#000000', x=>$x, y=>$y); return; } sub drawLines { my ($image, $size, $cellNum) = @_; my $xmax = $xOrig + $size - 1; my $ymax = $yOrig + $size - 1; my $x = $xOrig + $scale*$cellNum; my $y = $yOrig + $scale*$cellNum; $image->Draw(primitive=>'line', stroke=>'#000000', points=>"$xOrig,$y $xmax,$y", linewidth=>5); $image->Draw(primitive=>'line', stroke=>'#000000', points=>"$x,$yOrig $x,$ymax", linewidth=>5); return; }