image2mozaic.pl 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 13 August 2016
  5. # Website: https://github.com/trizen
  6. # Transform a regular image into a circle mozaic image.
  7. use 5.010;
  8. use strict;
  9. use warnings;
  10. use Imager;
  11. my $radius = 4;
  12. my $space = 3;
  13. sub image2mozaic {
  14. my ($img, $outfile) = @_;
  15. my $width = $img->getwidth;
  16. my $height = $img->getheight;
  17. my $thumb = $img->scale(scalefactor => 1 / ($radius * $space));
  18. my $thumb_width = $thumb->getwidth;
  19. my $thumb_height = $thumb->getheight;
  20. my @matrix;
  21. foreach my $y (0 .. $thumb_height - 1) {
  22. push @matrix, [map {
  23. [$thumb->getpixel(y => $y, x => $_)->rgba]
  24. } (0 .. $thumb_width - 1)];
  25. }
  26. my $scale_x = int($width / $thumb_width);
  27. my $scale_y = int($height / $thumb_height);
  28. my $mozaic = Imager->new(
  29. xsize => $scale_x * $thumb_width,
  30. ysize => $scale_y * $thumb_height,
  31. channels => 3,
  32. );
  33. my $color = Imager::Color->new(0, 0, 0);
  34. foreach my $i (0 .. $#matrix) {
  35. my $row = $matrix[$i];
  36. foreach my $j (0 .. $#{$row}) {
  37. $color->set(@{$row->[$j]});
  38. $mozaic->circle(
  39. r => $radius,
  40. x => int($radius + $j * $scale_x + rand($space)),
  41. y => int($radius + $i * $scale_y + rand($space)),
  42. color => $color,
  43. );
  44. }
  45. }
  46. $mozaic->write(file => $outfile);
  47. }
  48. my $file = shift(@ARGV) // die "usage: $0 [image]";
  49. my $img = Imager->new(file => $file) // die "can't load image `$file': $!";
  50. image2mozaic($img, 'circle_mozaic.png');