fractal_frame_transparent.pl 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 27 January 2018
  5. # https://github.com/trizen
  6. # Adds a transparent Mandelbrot-like fractal frame around the edges of an image.
  7. use 5.020;
  8. use strict;
  9. use warnings;
  10. use feature qw(lexical_subs);
  11. use experimental qw(signatures);
  12. use Imager;
  13. use Math::GComplex qw(cplx);
  14. sub complex_transform ($file) {
  15. my $img = Imager->new(file => $file);
  16. my $width = $img->getwidth;
  17. my $height = $img->getheight;
  18. my $max_iter = 10;
  19. my sub mandelbrot ($x, $y) {
  20. my $z = cplx(
  21. (2 * $x - $width) / $width,
  22. (2 * $y - $height) / $height,
  23. );
  24. my $c = $z;
  25. my $i = $max_iter;
  26. while (abs($z) < 2 and --$i) {
  27. $z = $z->pown(5) + $c;
  28. }
  29. ($max_iter - $i) / $max_iter;
  30. }
  31. foreach my $y (0 .. $height - 1) {
  32. foreach my $x (0 .. $width - 1) {
  33. my $i = mandelbrot($x, $y);
  34. my $pixel = $img->getpixel(x => $x, y => $y);
  35. my ($red, $green, $blue, $alpha) = $pixel->rgba();
  36. $red *= $i;
  37. $green *= $i;
  38. $blue *= $i;
  39. $alpha *= $i;
  40. $pixel->set($red, $green, $blue, $alpha);
  41. $img->setpixel(
  42. x => $x,
  43. y => $y,
  44. color => $pixel,
  45. );
  46. }
  47. }
  48. return $img;
  49. }
  50. sub usage {
  51. die "usage: $0 [input image] [output image]\n";
  52. }
  53. my $input = shift(@ARGV) // usage();
  54. my $output = shift(@ARGV) // 'fractal_frame.png';
  55. complex_transform($input)->write(file => $output);