favicon_mongler.pl 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #!/usr/bin/env perl
  2. use v5.36;
  3. use re '/aa';
  4. use Cwd ();
  5. use File::Basename ();
  6. use File::Which ();
  7. use File::Copy ();
  8. =head1 SYNOPSIS
  9. Render a favicon SVG out to every size and format a browser might ask for.
  10. =head2 USAGE
  11. bin/favicon_mongler.pl /path/to/favicon.svg
  12. Writes favicon-<size>.<ext> next to the source SVG for each size below, and
  13. copies the 32x32 .ico to favicon.ico, which is what browsers guess at when a
  14. page doesn't tell them otherwise.
  15. The sizes are the ones which actually get asked for: 32 for the tab, 48 for the
  16. desktop shortcut, 167 and 180 for iPads and iPhones, and 192 and 512 for the
  17. web app manifest.
  18. =head2 CAVEATS
  19. Needs inkscape on the PATH to do the rendering, and dies if it isn't there.
  20. Overwrites whatever is already at those paths without asking.
  21. =cut
  22. die "Usage:\n favicon_mongler.pl /path/to/favicon.svg" unless $ARGV[0];
  23. my $icon = Cwd::abs_path( $ARGV[0] );
  24. my $bin = File::Which::which('inkscape');
  25. die "Please install inkscape" if !$bin;
  26. my $dir = File::Basename::dirname($icon) || die "Can't figure out dir from $icon";
  27. my %files = (
  28. 32 => 'ico',
  29. 48 => 'png',
  30. 167 => 'png',
  31. 180 => 'png',
  32. 192 => 'png',
  33. 512 => 'png',
  34. );
  35. foreach my $size ( sort { $b <=> $a } keys(%files) ) {
  36. print "*** Generating ${size}x${size} .$files{$size} now... ***\n";
  37. my @cmd = ( $bin, '-w', $size, '-h', $size, $icon, '-e', "$dir/favicon-$size.$files{$size}" );
  38. # There is no maintained Perl SVG rasterizer to bind instead -- Imager has
  39. # no SVG reader, and Image::LibRSVG was last released in 2006 -- so driving
  40. # the renderer as a subprocess is the only option here.
  41. system(@cmd) and die "Failed to run @cmd: " . ( $? == -1 ? $! : 'exit status ' . ( $? >> 8 ) ); ## no critic (logicLAB::ProhibitShellDispatch)
  42. print "*** Wrote $dir/favicon-$size.$files{$size} ***\n\n";
  43. }
  44. File::Copy::copy( "$dir/favicon-32.ico", "$dir/favicon.ico" );
  45. 0;