image2digits.pl 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/perl
  2. # Author: Trizen
  3. # Date: 29 April 2022
  4. # https://github.com/trizen
  5. # Generate an ASCII representation for an image, using only digits.
  6. # See also:
  7. # https://github.com/TotalTechGeek/pictoprime
  8. use 5.010;
  9. use strict;
  10. use autodie;
  11. use warnings;
  12. use GD qw();
  13. use List::Util qw(max);
  14. use Getopt::Long qw(GetOptions);
  15. GD::Image->trueColor(1);
  16. my $size = 80;
  17. sub help {
  18. my ($code) = @_;
  19. print <<"HELP";
  20. usage: $0 [options] [files]
  21. options:
  22. -w --width=i : width size of the ASCII image (default: $size)
  23. example:
  24. perl $0 --width 200 image.png
  25. HELP
  26. exit($code);
  27. }
  28. GetOptions('w|width=s' => \$size,
  29. 'h|help' => sub { help(0) },)
  30. or die "Error in command-line arguments!";
  31. sub map_value {
  32. my ($value, $in_min, $in_max, $out_min, $out_max) = @_;
  33. ($value - $in_min) * ($out_max - $out_min) / ($in_max - $in_min) + $out_min;
  34. }
  35. my @digits = split(//, "7772299408");
  36. #my @digits = 0..9;
  37. sub img2digits {
  38. my ($image) = @_;
  39. my $img = GD::Image->new($image) // return;
  40. my ($width, $height) = $img->getBounds;
  41. if ($size != 0) {
  42. my $scale_width = $size;
  43. my $scale_height = int($height / ($width / ($size / 2)));
  44. my $resized = GD::Image->new($scale_width, $scale_height);
  45. $resized->copyResampled($img, 0, 0, 0, 0, $scale_width, $scale_height, $width, $height);
  46. ($width, $height) = ($scale_width, $scale_height);
  47. $img = $resized;
  48. }
  49. my $avg = 0;
  50. my @averages;
  51. foreach my $y (0 .. $height - 1) {
  52. foreach my $x (0 .. $width - 1) {
  53. my $index = $img->getPixel($x, $y);
  54. my ($r, $g, $b) = $img->rgb($index);
  55. my $value = max($r, $g, $b);
  56. push @averages, $digits[map_value($value, 0, 255, 0, $#digits)];
  57. }
  58. }
  59. unpack("(A$width)*", join('', @averages));
  60. }
  61. say for img2digits($ARGV[0] // help(1));