sub wxColor2hex { my $color = shift; my $red = $color->Red(); my $green = $color->Green(); my $blue = $color->Blue(); return sprintf("#%0x%0x%0x", $red,$green,$blue); } sub ReadImageMagick { my $file = shift; my ($x, $y, $caption, $bgcolor, $blowup, $parent_background) = @_; $caption ||=''; $blowup ||=0; # if the file is not readable, return a bitmap with just a questionmark return DrawCaption($x, $y, '?', $bgcolor, $parent_background) unless -r $file; # The previous version needed colors to be defined as Wx::Colour-s, now # we need the html-color code $bgcolor = $parent_background unless defined $bgcolor; my $ibg = wxColor2hex($bgcolor) if (ref($bgcolor) eq 'Wx::Colour'); my $pbg = wxColor2hex($parent_background) if (ref($parent_background) eq 'Wx::Colour'); # $cache is a global, first we check if the file is in cache already my $image = $cache->get("$file-$x-$y-$caption-$ibg-$blowup-$pbg"); if (!$image) { # We're using a roundcornered background, created by this little piece of SVG my $radius = 10; my $svg = < SVG my $background=Image::Magick->new(magick => 'svg'); $background->Set('background' => $pbg); $background->blobtoimage($svg); # Now we determine the fontsize we're going to use for the caption under the image my ($textheight, $textwidth) = (0,0); if ($caption) { my $pt = 20; do { (undef, undef, undef, undef, $textwidth, $textheight, undef) = $background->QueryFontMetrics(text => $caption, font => 'Comic-Sans-MS', pointsize => $pt, gravity => 'South'); $pt--; } until ($textwidth < $x) && ($textheight < $y/5); $background->Annotate(text => $caption, font => 'Comic-Sans-MS', pointsize => $pt, gravity => 'South'); } # Read the actual image my $img = Image::Magick->new; my $rc = $img->Read($file); carp "Can't read $file: $rc" if $rc; # We'll fake transparency by using white as the transparent color...crappy, but it looks # rather good most of the time $img->Transparent(color => 'white') if (!$img->Get('matte') || $file =~ /wmf$/i); # Now we'll make the image fit within the part that is not used by the caption my $w = $img->Get('width'); my $h = $img->Get('height'); my $ch = $textheight; # if the image is too large, resize it to make it fit if (($w > $x) || ($h > ($y-$ch))) { my ($newx, $newy) = ($w, $h); if ($w > $x) { my $factor = $w/$x; # return a null-bitmap if factor is 0 return wxNullBitmap if not $factor; $newy = int($h/$factor); ($w,$h) = ($x, $newy); } if ($h > ($y-$ch)) { my $factor = $h/($y-$ch); # return a null-bitmap if factor is 0 return wxNullBitmap if not $factor; ($w, $h) = (int($w/$factor),$y-$ch); } $img->Thumbnail(height => $h, width =>$w ); } # If the image is too small, and we specified that we want to blowup the image.. elsif ($blowup) { my $factor = $w/$x; # return a null-bitmap if factor is 0 return wxNullBitmap if not $factor; my $newy = int($h/$factor); ($w,$h) = ($x, $newy); if ($h > ($y-$ch)) { my $factor = $h/($y-$ch); return wxNullBitmap if not $factor; ($w, $h) = (int($w/$factor),$y-$ch); } $img->Resize(height => $h, width =>$w ); } # we center the image by adding equal borders around it $img->Border( width => int(($x - $img->Get('width'))/2) - $radius/2, height => int((($y-$textheight) - $img->Get('height'))/2) - $radius/2, fill => $ibg); # Call the Composite method of the background image, with the image as an argument. $background->Composite(image=>$img,compose=>'over', gravity => 'North'); $background->Set(quality=>100); # We return the image as a PNG $background->Set(magick => 'png'); $image = $background->imagetoblob(); # Now we can put it in the cache $cache->set("$file-$x-$y-$caption-$ibg-$blowup-$pbg", $image); # I added this hoping that the pagefault on W98 would disappear, but it didn't work... :( undef $background; undef $img; } my $fh = IO::Scalar->new(\$image); my $contenttype = 'image/png'; return Wx::Bitmap->new(Wx::Image->newStreamMIME($fh, $contenttype)) }