sharp_2x_zoom.pl 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 31 October 2015
  5. # Website: https://github.com/trizen
  6. # Zoom a picture two times, without loosing too much details.
  7. # Requires: wkhtmltoimage
  8. use 5.010;
  9. use strict;
  10. use autodie;
  11. use warnings;
  12. use GD qw();
  13. use File::Temp qw(tempfile);
  14. use HTML::Entities qw(encode_entities);
  15. GD::Image->trueColor(1);
  16. sub help {
  17. my ($code) = @_;
  18. print <<"HELP";
  19. usage: $0 [input image] [output image]
  20. HELP
  21. exit($code);
  22. }
  23. sub enhance_img {
  24. my ($image, $out) = @_;
  25. my $img = GD::Image->new($image) // return;
  26. my ($width, $height) = $img->getBounds;
  27. my $scale_width = 2 * $width;
  28. my $scale_height = $height;
  29. my $resized = GD::Image->new($scale_width, $scale_height);
  30. $resized->copyResampled($img, 0, 0, 0, 0, $scale_width, $scale_height, $width, $height);
  31. ($width, $height) = ($scale_width, $scale_height);
  32. $img = $resized;
  33. my @pixels;
  34. foreach my $y (0 .. $height - 1) {
  35. foreach my $x (0 .. $width - 1) {
  36. my $index = $img->getPixel($x, $y);
  37. push @pixels, [$img->rgb($index)];
  38. }
  39. }
  40. my $header = <<"EOT";
  41. <html xmlns="https://www.w3.org/1999/xhtml">
  42. <head>
  43. <title>${\encode_entities($image)}</title>
  44. <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  45. <style type="text/css">
  46. /*<![CDATA[*/
  47. <!--
  48. pre {
  49. font-size: 1;
  50. font-family: monospace;
  51. }
  52. EOT
  53. my $footer = <<'EOT';
  54. </pre></body></html>
  55. EOT
  56. my %colors;
  57. my $style = '';
  58. my @html;
  59. my $name = 'A';
  60. while (@pixels) {
  61. push @html, [
  62. map {
  63. my $color = sprintf("%02x%02x%02x", @{$_});
  64. if (not exists $colors{$color}) {
  65. $colors{$color} = $name;
  66. $style .= ".$name\{background-color:#$color;}\n";
  67. $name++;
  68. }
  69. $colors{$color};
  70. } splice(@pixels, 0, $width)
  71. ];
  72. }
  73. my $html = '';
  74. foreach my $row (@html) {
  75. while (@{$row}) {
  76. my $class = shift @{$row};
  77. my $count = 1;
  78. while (@{$row} and $row->[0] eq $class) {
  79. ++$count;
  80. shift @{$row};
  81. }
  82. $html .= qq{<span class="$class">} . (' ' x $count) . "</span>";
  83. }
  84. $html .= '<br/>';
  85. }
  86. $style .= <<'EOT';
  87. -->
  88. /*]]>*/
  89. </style>
  90. </head>
  91. <body>
  92. <pre>
  93. EOT
  94. $html = join('', $header, $style, $html, $footer);
  95. my ($fh, $tmpfile) = tempfile(UNLINK => 1, SUFFIX => '.html');
  96. print $fh $html;
  97. close $fh;
  98. system(
  99. 'wkhtmltoimage', '--quality', '100', '--crop-h', $height * 2,
  100. '--crop-w', $width, '--crop-x', '8', '--crop-y',
  101. '8', '--transparent', '--quiet', $tmpfile, $out
  102. );
  103. }
  104. my $img = $ARGV[0] // help(1);
  105. my $out = $ARGV[1] // help(1);
  106. enhance_img($img, $out);