Alex 'AdUser' Z
7 years ago
1 changed files with 168 additions and 0 deletions
@ -0,0 +1,168 @@ |
|||||||
|
package CMTD::Captcha; |
||||||
|
|
||||||
|
use strict; |
||||||
|
use warnings; |
||||||
|
use utf8; |
||||||
|
|
||||||
|
use Imager; |
||||||
|
|
||||||
|
our $VERSION = 0.01; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my ($class, %config) = @_; |
||||||
|
my $self = { |
||||||
|
width => 120, |
||||||
|
height => 40, |
||||||
|
bg_color => '#444444', |
||||||
|
fg_color => '#999999', |
||||||
|
expire => 300, |
||||||
|
debug => 0, |
||||||
|
length => 6, |
||||||
|
ft_file => undef, |
||||||
|
ft_size => 32, |
||||||
|
ft_family => 'SansSerif', |
||||||
|
wv_size => 5, |
||||||
|
wv_length => 60, |
||||||
|
%config |
||||||
|
}; |
||||||
|
|
||||||
|
die("Captcha : ft_file not set\n") unless ($self->{ft_file}); |
||||||
|
|
||||||
|
return bless $self, $class; |
||||||
|
} |
||||||
|
|
||||||
|
sub _gen_code { |
||||||
|
my ($self) = @_; |
||||||
|
my ($code, $pos); |
||||||
|
|
||||||
|
my @chars = ('a' .. 'f', '0' .. '9'); |
||||||
|
my $length = $self->{length}; |
||||||
|
|
||||||
|
$code = ""; |
||||||
|
while ($length --> 0) { |
||||||
|
$pos = int rand scalar(@chars); |
||||||
|
$code .= $chars[$pos]; |
||||||
|
} |
||||||
|
|
||||||
|
return $code; |
||||||
|
} |
||||||
|
|
||||||
|
sub create { |
||||||
|
my ($self) = @_; |
||||||
|
my ($code, $data, $err); |
||||||
|
|
||||||
|
eval { |
||||||
|
warn "Generating code\n" if $self->{debug}; |
||||||
|
$code = $self->_gen_code(); |
||||||
|
warn "Code is: $code\n" if $self->{debug}; |
||||||
|
|
||||||
|
my $image = Imager->new( |
||||||
|
xsize => $self->{width}, |
||||||
|
ysize => $self->{height}, |
||||||
|
); |
||||||
|
|
||||||
|
warn "Creating image (1/3)\n" if $self->{debug}; |
||||||
|
$image->box(filled => 1, color => $self->{bg_color}); |
||||||
|
|
||||||
|
# calculate position of bottom left corner of text box |
||||||
|
warn "Creating font\n" if $self->{debug}; |
||||||
|
my $font = Imager::Font->new( |
||||||
|
file => $self->{ft_file}, |
||||||
|
size => $self->{ft_size}, |
||||||
|
color => $self->{fg_color}, |
||||||
|
) or die("can't create font: ", Imager->errstr, "\n"); |
||||||
|
|
||||||
|
warn "Creating image (2/3)\n" if $self->{debug}; |
||||||
|
$font->align( |
||||||
|
string => $code, |
||||||
|
halign => 'center', |
||||||
|
valign => 'center', |
||||||
|
image => $image, |
||||||
|
x => $image->getwidth / 2, |
||||||
|
y => $image->getheight / 2, |
||||||
|
) or die("can't place code on image\n"); |
||||||
|
|
||||||
|
$image->filter( |
||||||
|
type => 'noise', |
||||||
|
amount => 120, |
||||||
|
subtype => 0, |
||||||
|
) or die("can't distort image\n"); |
||||||
|
|
||||||
|
$image = $image->convert(preset => 'grey'); |
||||||
|
|
||||||
|
warn "Saving image\n" if ($self->{debug}); |
||||||
|
$image->write(data => \$data, type => 'jpeg') |
||||||
|
or die("can't write image: " . Imager->errstr . "\n"); |
||||||
|
|
||||||
|
$self->{error} = ''; 1; |
||||||
|
} or do { |
||||||
|
warn "Error: $@" if ($self->{debug}); |
||||||
|
$self->{error} = $@; |
||||||
|
return; |
||||||
|
}; |
||||||
|
|
||||||
|
return ($code, $data); |
||||||
|
} |
||||||
|
|
||||||
|
sub error { |
||||||
|
my ($self) = @_; |
||||||
|
return $self->{error} || ''; |
||||||
|
} |
||||||
|
|
||||||
|
1; |
||||||
|
|
||||||
|
=pod |
||||||
|
|
||||||
|
=head1 NAME |
||||||
|
|
||||||
|
CMTD::Captcha -- generate captcha with Imager |
||||||
|
|
||||||
|
=head1 DESCRIPTION |
||||||
|
|
||||||
|
Based on Mojolicious::Plugin::CaptchaRenderer, but uses Imager instead. |
||||||
|
|
||||||
|
=head1 Methods / Private |
||||||
|
|
||||||
|
=head2 C<_gen_code> |
||||||
|
|
||||||
|
Generate captcha code for placing to image. |
||||||
|
|
||||||
|
=head1 Methods / Public |
||||||
|
|
||||||
|
=head2 C<new> |
||||||
|
|
||||||
|
my $captcha = CMTD::Captcha->new(%config); |
||||||
|
|
||||||
|
Constructor. Takes plain hash of options. Mandatory settings: |
||||||
|
|
||||||
|
* ft_file -- default: undef, file with font to use |
||||||
|
|
||||||
|
Optional settings: |
||||||
|
|
||||||
|
* width -- 120, image width |
||||||
|
* height -- 30, image height |
||||||
|
* bg_color -- '#444444', base background color for image |
||||||
|
* fg_color -- '#999999', color of text |
||||||
|
* debug -- 0, display diagnostic messages to stderr |
||||||
|
* ft_size -- 32, font size, points |
||||||
|
* ft_family -- 'SansSerif', font family |
||||||
|
* wv_size -- 5, distortion settings, vertical amplitude |
||||||
|
* wv_length -- 60, distortion settings, wave length |
||||||
|
|
||||||
|
=head2 C<create> |
||||||
|
|
||||||
|
my $captcha = CMTD::Captcha->new(%config); |
||||||
|
my ($code, $data) = $captcha->create(); |
||||||
|
|
||||||
|
Generates captcha image, returns hash of filename. |
||||||
|
|
||||||
|
=head2 C<error> |
||||||
|
|
||||||
|
my $captcha = CMTD::Captcha->new(%config); |
||||||
|
...do something wrong... |
||||||
|
my $error = $captcha->error; |
||||||
|
|
||||||
|
Returns last occured error for method C<create> |
||||||
|
Error will be cleared on next successfull call to these methods. |
||||||
|
|
||||||
|
=cut |
Loading…
Reference in new issue