gif2webp.pl 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/perl
  2. # Author: Trizen
  3. # Date: 14 October 2023
  4. # https://github.com/trizen
  5. # Convert GIF animations to WEBP animations, using the `gif2webp` tool from "libwebp".
  6. # The original GIF files are deleted.
  7. use 5.036;
  8. use File::Find qw(find);
  9. use Getopt::Long qw(GetOptions);
  10. my $gif2webp_cmd = "gif2webp"; # `gif2webp` command
  11. my $use_exiftool = 0; # true to use `exiftool` instead of `File::MimeInfo::Magic`
  12. `$gif2webp_cmd -h`
  13. or die "Error: `$gif2webp_cmd` tool from 'libwebp' is not installed!\n";
  14. sub gif2webp ($file) {
  15. my $orig_file = $file;
  16. my $webp_file = $file;
  17. if ($webp_file =~ s/\.gif\z/.webp/i) {
  18. ## ok
  19. }
  20. else {
  21. $webp_file .= '.webp';
  22. }
  23. if (-e $webp_file) {
  24. warn "[!] File <<$webp_file>> already exists...\n";
  25. next;
  26. }
  27. system($gif2webp_cmd, '-lossy', $orig_file, '-o', $webp_file);
  28. if ($? == 0 and (-e $webp_file) and ($webp_file ne $orig_file)) {
  29. unlink($orig_file);
  30. }
  31. else {
  32. return;
  33. }
  34. return 1;
  35. }
  36. sub determine_mime_type ($file) {
  37. if ($file =~ /\.gif\z/i) {
  38. return "image/gif";
  39. }
  40. if ($use_exiftool) {
  41. my $res = `exiftool \Q$file\E`;
  42. $? == 0 or return;
  43. defined($res) or return;
  44. if ($res =~ m{^MIME\s+Type\s*:\s*(\S+)}mi) {
  45. return $1;
  46. }
  47. return;
  48. }
  49. require File::MimeInfo::Magic;
  50. File::MimeInfo::Magic::magic($file);
  51. }
  52. my %types = (
  53. 'image/gif' => {
  54. call => \&gif2webp,
  55. },
  56. );
  57. GetOptions('exiftool!' => \$use_exiftool,)
  58. or die "Error in command-line arguments!";
  59. @ARGV or die <<"USAGE";
  60. usage: $0 [options] [dirs | files]
  61. options:
  62. --exiftool : use `exiftool` to determine the MIME type (default: $use_exiftool)
  63. USAGE
  64. find(
  65. {
  66. no_chdir => 1,
  67. wanted => sub {
  68. (-f $_) || return;
  69. my $type = determine_mime_type($_) // return;
  70. if (exists $types{$type}) {
  71. $types{$type}{call}->($_);
  72. }
  73. }
  74. } => @ARGV
  75. );
  76. say ":: Done!";