bitmap_monochrome_encoding_decoding.pl 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 24 August 2018
  4. # https://github.com/trizen
  5. # Encode an image into an integer in monochrome bitmap format.
  6. # Decode an integer back into a monochrome image, by specifying XSIZE and YSIZE.
  7. # Usage:
  8. # perl bitmap_monochrome_encoding_decoding.pl [image|integer] [xsize] [ysize]
  9. # See also:
  10. # https://www.youtube.com/watch?v=_s5RFgd59ao
  11. # https://en.wikipedia.org/wiki/Tupper's_self-referential_formula
  12. # For example, try:
  13. # perl bitmap_monochrome_encoding_decoding.pl 960939379918958884971672962127852754715004339660129306651505519271702802395266424689642842174350718121267153782770623355993237280874144307891325963941337723487857735749823926629715517173716995165232890538221612403238855866184013235585136048828693337902491454229288667081096184496091705183454067827731551705405381627380967602565625016981482083418783163849115590225610003652351370343874461848378737238198224849863465033159410054974700593138339226497249461751545728366702369745461014655997933798537483143786841806593422227898388722980000748404719
  14. # perl bitmap_monochrome_encoding_decoding.pl 4858487700955227269310810743279699920059071665868862676453015679577225782068321715691954329017884722389385550282344094325110559671706720456802995614421319713836803680439230203857023532236791776607932309358505788694249724093972434433440785815336774291945612106058206332142360075310011570794409292417648253014388444262569443218615514272957841814202800720702726236206242071675013681230087031878381452808096784548757607453284867359002454455428928632983954826623474612688372970630260114784068636783069647343475295488391045284413477645076796807315439
  15. use 5.020;
  16. use strict;
  17. use warnings;
  18. my $XSIZE = 106;
  19. my $YSIZE = 17;
  20. use Imager;
  21. use Math::AnyNum;
  22. use experimental qw(signatures);
  23. sub bitmap_monochrome_encoding ($file) {
  24. my $img = Imager->new(file => $file)
  25. or die "Can't open file `$file`: $!";
  26. $XSIZE = $img->getwidth;
  27. $YSIZE = $img->getheight;
  28. say "XSIZE = $XSIZE";
  29. say "YSIZE = $YSIZE";
  30. my $bin = '';
  31. foreach my $x (0 .. $XSIZE - 1) {
  32. foreach my $y (0 .. $YSIZE - 1) {
  33. my ($R, $G, $B) = $img->getpixel(x => $x, y => $YSIZE - $y - 1)->rgba;
  34. if ($R + $G + $B >= 3 * 128) {
  35. $bin .= '1';
  36. }
  37. else {
  38. $bin .= '0';
  39. }
  40. }
  41. }
  42. Math::AnyNum->new($bin, 2) * $YSIZE;
  43. }
  44. sub bitmap_monochrome_decoding ($k) {
  45. my $red = Imager::Color->new('#FFFFFF');
  46. my $img = Imager->new(xsize => $XSIZE,
  47. ysize => $YSIZE);
  48. my @bin = split(//, reverse(($k / $YSIZE)->floor->as_bin));
  49. for (my $y = 0 ; @bin ; ++$y) {
  50. my @row = splice(@bin, 0, $YSIZE);
  51. foreach my $i (0 .. $XSIZE - 1) {
  52. $img->setpixel(x => $XSIZE - $y - 1, y => $i, color => $red) if $row[$i];
  53. }
  54. }
  55. $img->write(file => 'monochrome_image.png');
  56. }
  57. @ARGV || die "usage: $0 [image|integer] [xsize] [ysize]\n";
  58. $XSIZE = $ARGV[1] if defined($ARGV[1]);
  59. $YSIZE = $ARGV[2] if defined($ARGV[2]);
  60. my $k = 0;
  61. if ($ARGV[0] =~ /^[0-9]+\z/) {
  62. say "[*] Decoding...";
  63. $k = Math::AnyNum->new($ARGV[0]);
  64. }
  65. else {
  66. say "[*] Encoding...";
  67. my $img_file = $ARGV[0];
  68. $k = bitmap_monochrome_encoding($img_file);
  69. say "k = $k";
  70. }
  71. bitmap_monochrome_decoding($k);
  72. say "[*] Done!"