image2png.pl 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #!/usr/bin/perl
  2. # Author: Trizen
  3. # Date: 19 December 2021
  4. # Edit: 31 July 2022
  5. # https://github.com/trizen
  6. # Convert any images to PNG, using the Gtk3::Gdk::Pixbuf library.
  7. # It can convert SVG, WEBP, JPEG, and more...
  8. use 5.020;
  9. use strict;
  10. use warnings;
  11. use experimental qw(signatures);
  12. use Gtk3 qw(-init);
  13. use File::Spec::Functions qw(catfile);
  14. use File::Basename qw(dirname basename);
  15. use Getopt::Long qw(GetOptions);
  16. my %CONFIG = (
  17. output_dir => undef,
  18. width => undef,
  19. height => undef,
  20. scale_factor => undef,
  21. flipx => undef,
  22. flipy => undef,
  23. remove => 0,
  24. );
  25. sub help ($exit_code = 0) {
  26. print <<"EOT";
  27. Usage: $0 [OPTIONS] [<images>]
  28. -w, --width=WIDTH Width of output image in pixels
  29. -h, --height=HEIGHT Height of output image in pixels
  30. -s, --scale=FACTOR Scale image by FACTOR
  31. -d, --dir=DIRECTORY Output directory
  32. --flipx Flip X coordinates of image
  33. --flipy Flip Y coordinates of image
  34. --remove! Remove original files
  35. --help Give this help list
  36. EOT
  37. exit($exit_code);
  38. }
  39. GetOptions(
  40. "d|directory=s" => \$CONFIG{output_dir},
  41. "w|width=i" => \$CONFIG{width},
  42. "h|height=i" => \$CONFIG{height},
  43. "s|scale=f" => \$CONFIG{scale_factor},
  44. "flipx" => \$CONFIG{flipx},
  45. "flipy" => \$CONFIG{flipy},
  46. "remove!" => \$CONFIG{remove},
  47. 'help' => sub { help(0) },
  48. )
  49. or help(1);
  50. @ARGV || help(2);
  51. sub image2png ($input_file, $output_file = undef) {
  52. my $pixbuf;
  53. if (defined($CONFIG{width}) or defined($CONFIG{height})) {
  54. my $width = $CONFIG{width} // do {
  55. my (undef, $x, $y) = Gtk3::Gdk::Pixbuf::get_file_info($input_file);
  56. int($x / ($y / $CONFIG{height}));
  57. };
  58. my $height = $CONFIG{height} // $CONFIG{width};
  59. my $keep_aspect_ratio = ($CONFIG{width} && $CONFIG{height}) ? 0 : 1;
  60. $pixbuf = "Gtk3::Gdk::Pixbuf"->new_from_file_at_scale($input_file, $width, $height, $keep_aspect_ratio);
  61. }
  62. elsif (defined($CONFIG{scale_factor})) {
  63. my (undef, $width, $height) = Gtk3::Gdk::Pixbuf::get_file_info($input_file);
  64. my $scale = $CONFIG{scale_factor};
  65. $pixbuf = "Gtk3::Gdk::Pixbuf"->new_from_file_at_scale($input_file, $width * $scale, $height * $scale, 0);
  66. }
  67. else {
  68. $pixbuf = "Gtk3::Gdk::Pixbuf"->new_from_file($input_file);
  69. }
  70. if ($CONFIG{flipx}) {
  71. $pixbuf = $pixbuf->flip(1);
  72. }
  73. if ($CONFIG{flipy}) {
  74. $pixbuf = $pixbuf->flip(0);
  75. }
  76. if (defined($pixbuf)) {
  77. if (!defined($output_file)) {
  78. my $output_dir = $CONFIG{output_dir} // dirname($input_file);
  79. my $basename = basename($input_file);
  80. if (not $basename =~ s/\.(svg|jpe?g|webp|gif|avif|jfif|pjpeg|pjp|bmp|ico|tiff?|xpm)\z/.png/i) {
  81. $basename .= '.png';
  82. }
  83. if (not -d $output_dir) {
  84. require File::Path;
  85. File::Path::make_path($output_dir)
  86. || warn "Cannot create output directory <<$output_dir>>: $!\n";
  87. }
  88. $output_file = catfile($output_dir, $basename);
  89. }
  90. $pixbuf->save($output_file, 'png');
  91. return 1;
  92. }
  93. return undef;
  94. }
  95. foreach my $file (@ARGV) {
  96. say ":: Processing: $file";
  97. if (-e $file) {
  98. if (image2png($file)) {
  99. if ($CONFIG{remove}) {
  100. say ":: Removing original file...";
  101. unlink($file) or warn "Cannot remove file <<$file>>: $!\n";
  102. }
  103. }
  104. else {
  105. warn "Cannot convert file <<$file>>! Skipping...\n";
  106. }
  107. }
  108. else {
  109. warn "File <<$file>> does not exist! Skipping...\n";
  110. }
  111. }