image2html.pl 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 15 October 2015
  5. # Website: https://github.com/trizen
  6. # Generate an HTML representation of an image
  7. # (best viewed with Firefox)
  8. use 5.010;
  9. use strict;
  10. use autodie;
  11. use warnings;
  12. use GD qw();
  13. use Getopt::Long qw(GetOptions);
  14. use HTML::Entities qw(encode_entities);
  15. GD::Image->trueColor(1);
  16. my $size = 500;
  17. my $font_size = 1;
  18. sub help {
  19. my ($code) = @_;
  20. print <<"HELP";
  21. usage: $0 [options] [files]
  22. options:
  23. -w --width=i : scale the image to this width (default: $size)
  24. -f --font-size=i : HTML font size property (default: $font_size)
  25. example:
  26. perl $0 --width 800 image.png
  27. HELP
  28. exit($code);
  29. }
  30. GetOptions(
  31. 'w|width=i' => \$size,
  32. 'f|font-size=f' => \$font_size,
  33. 'h|help' => sub { help(0) },
  34. )
  35. || die "Error in command-line arguments!";
  36. sub img2html {
  37. my ($image) = @_;
  38. my $img = GD::Image->new($image) // return;
  39. my ($width, $height) = $img->getBounds;
  40. if ($size != 0) {
  41. my $scale_width = $size;
  42. my $scale_height = int($height / ($width / ($size / 2)));
  43. my $resized = GD::Image->new($scale_width, $scale_height);
  44. $resized->copyResampled($img, 0, 0, 0, 0, $scale_width, $scale_height, $width, $height);
  45. ($width, $height) = ($scale_width, $scale_height);
  46. $img = $resized;
  47. }
  48. my @pixels;
  49. foreach my $y (0 .. $height - 1) {
  50. foreach my $x (0 .. $width - 1) {
  51. my $index = $img->getPixel($x, $y);
  52. push @pixels, [$img->rgb($index)];
  53. }
  54. }
  55. my $header = <<"EOT";
  56. <html xmlns="https://www.w3.org/1999/xhtml">
  57. <head>
  58. <title>${\encode_entities($image)}</title>
  59. <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  60. <style type="text/css">
  61. /*<![CDATA[*/
  62. <!--
  63. pre {
  64. font-size: $font_size;
  65. font-family: monospace;
  66. }
  67. EOT
  68. my $footer = <<'EOT';
  69. </pre>
  70. </body>
  71. </html>
  72. EOT
  73. my %colors;
  74. my $style = '';
  75. my @html;
  76. my $name = 'A';
  77. while (@pixels) {
  78. push @html, [
  79. map {
  80. my $color = sprintf("%02x%02x%02x", @{$_});
  81. if (not exists $colors{$color}) {
  82. $colors{$color} = $name;
  83. $style .= ".$name\{background-color:#$color;}\n";
  84. $name++;
  85. }
  86. $colors{$color};
  87. } splice(@pixels, 0, $width)
  88. ];
  89. }
  90. my $html = '';
  91. foreach my $row (@html) {
  92. while (@{$row}) {
  93. my $class = shift @{$row};
  94. my $count = 1;
  95. while (@{$row} and $row->[0] eq $class) {
  96. ++$count;
  97. shift @{$row};
  98. }
  99. $html .= qq{<span class="$class">} . (' ' x $count) . "</span>";
  100. }
  101. $html .= '<br/>';
  102. }
  103. $style .= <<'EOT';
  104. -->
  105. /*]]>*/
  106. </style>
  107. </head>
  108. <body>
  109. <pre>
  110. EOT
  111. join('', $header, $style, $html, $footer);
  112. }
  113. say img2html($ARGV[0] // help(1));