Acme-DreamyImage
view release on metacpan or search on metacpan
lib/Acme/DreamyImage.pm view on Meta::CPAN
package Acme::DreamyImage;
use strict;
use warnings;
our $VERSION = '2.0';
use Object::Tiny qw(seed width height);
use self;
use Imager qw(:handy);
use Digest::SHA1 qw(sha1_hex);
sub new {
$self = $self->SUPER::new(@args);
die "'seed' is required\n" unless defined $self->{seed};
die "'width' is required, and cannot be 0.\n" unless defined $self->{width} && $self->{width} > 0;
die "'height' is required, and cannot be 0.\n" unless defined $self->{height} && $self->{height} > 0;
$self->{seed} = sha1_hex($self->seed);
return $self;
}
sub write {
my $image = $self->random_image;
$image->write(@args) or die $image->errstr;
return $self;
}
sub random {
my ($upper_bound) = @args;
$upper_bound ||= 1;
$self->{pos} = 0 unless defined($self->{pos});
my $value = substr($self->{seed}, $self->{pos}, 1);
$self->{pos} += 1;
$self->{pos} = 0 if $self->{pos} >= length($self->{seed});
return int(hex($value) / 15 * $upper_bound);
}
sub random_color {
return [map { $self->random(255) } 1..4]
}
my @types = Imager->combines;
sub random_combine_type {
my $i = $self->random( 0+ @types );
return $types[$i];
}
sub random_background {
my $image = Imager->new(xsize => $self->width, ysize => $self->height, channels => 3);
$image->box(filled => 1, color => [255, 255, 255]);
$image->filter(type => "gradgen",
xo => [map { $self->random($self->width) } 1..2],
yo => [map { $self->random($self->height) } 1..2],
colors => [ map { $self->random_color } 1..2 ]);
$image->filter(type => "noise", subtype => 0, amount => $self->random(10));
$image->filter(type => "gaussian", stddev => $self->random( ($self->width + $self->height) / 2 * 0.03 ));
return $image;
}
sub new_layer {
my ($xsize, $ysize, $cb) = @_;
my $layer = Imager->new(xsize => $xsize, ysize => $ysize, channels => 4);
$cb->($layer);
return $layer;
}
sub random_image {
my $image = $self->random_background;
my $xsize = $self->width;
my $ysize = $self->height;
new_layer(
$xsize, $ysize,
sub {
my ($layer) = @_;
my $xymax = $xsize > $ysize ? $xsize : $ysize;
for (1..$self->random(24)) {
$layer->arc(
color => $self->random_color,
r => $self->random($xymax),
x => $self->random($xsize),
y => $self->random($ysize),
d1 => $self->random(180),
d2 => $self->random(360),
);
}
$layer->filter(type => "gaussian", stddev => $self->random(30));
$image->compose(src => $layer, tx => 0, ty => 0, combine => 'add');
}
) if $self->random(6) > 2;
# Big Blur Circles
( run in 1.328 second using v1.01-cache-2.11-cpan-d7f47b0818f )