Created
June 26, 2012 16:04
-
-
Save earino/2996703 to your computer and use it in GitHub Desktop.
Snippet of code using Inline::C and leptonica for super duper fast image resizing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# stuff setting up moose and the environment omitted | |
sub BUILD { | |
my $self = shift; | |
my $application_environment = $ENV{'APPLICATION_ENVIRONMENT'}; | |
my $conf = new Config::General($self->config_file); | |
my %config = $conf->getall; | |
my $environment = $config{'Transformer'}->{$application_environment}; | |
$self->temp_dir($environment->{'temp_dir'}); | |
$self->temp_file_template($environment->{'temp_file_template'}); | |
$self->inline_c_inc($environment->{'inline_c_inc'}); | |
$self->inline_c_auto_include($environment->{'inline_c_auto_include'}); | |
$self->inline_c_libs($environment->{'inline_c_libs'}); | |
$self->inline_c_build_directory($environment->{'inline_c_build_directory'}); | |
} | |
=back | |
=head2 Access | |
=over 4 | |
=item $image_transformer->transform(image_path => $path, x_scale => $xs, y_scale => $ys, return_type => $ret) | |
Transforms the image in path to the scale provided by x_scale and y_scale, and returns it as a return_type type image. | |
Return type myst be a string that contains either jpeg, jpg, gif, or png. Preferably in lower case. This code looks compilcated | |
in that the C source that is compiled is inlined as a HERE doc. This is done for performance purposes and reading it off a disk | |
every time it was called would just slow things down. We use the Inline::Bind method to do the actual inline magic. | |
=back | |
=cut | |
method transform (Str :$image_path, Int :$x_scale, Int :$y_scale, Str :$return_type) { | |
my $c_source = <<END; | |
SV* scale(char * image_path, int x_size, int y_size, char * temp_out, char * type) { | |
l_float32 scale_x, scale_y; | |
PIX *pixs, *pixd; | |
//read in the requested file FIXME | |
if ((pixs = pixRead(image_path)) == NULL) { | |
fprintf(stderr, "pixs not made from %s\\n", image_path); | |
return NULL; | |
} | |
if (-1 != x_size) { | |
scale_x = (l_float32) x_size / pixGetWidth(pixs); | |
} | |
if (-1 != y_size) { | |
scale_y = (l_float32) y_size / pixGetHeight(pixs); | |
} | |
if (-1 == x_size) { | |
scale_x = scale_y; | |
} | |
if (-1 == y_size) { | |
scale_y = scale_x; | |
} | |
if (-1 != x_size || -1 != y_size) { | |
pixd = pixScale(pixs, scale_x, scale_y); | |
} | |
else { | |
pixd = pixCopy(NULL, pixs); | |
} | |
l_uint8 *data; | |
size_t data_size; | |
if (0 == strcmp("jpeg", type) || 0 == strcmp("jpg", type)) { | |
pixWrite(temp_out, pixd, IFF_JFIF_JPEG); | |
} | |
else if (0 == strcmp("gif", type)) { | |
pixWrite(temp_out, pixd, IFF_GIF); | |
} | |
else if (0 == strcmp("png", type)) { | |
pixWrite(temp_out, pixd, IFF_PNG); | |
} | |
else if (0 == strcmp("tiff", type)) { | |
pixWrite(temp_out, pixd, IFF_TIFF); | |
} | |
SV* retval = newSVpvf(temp_out); | |
pixDestroy(&pixd); | |
pixDestroy(&pixs); | |
return retval; | |
} | |
END | |
if (! -e $self->inline_c_build_directory) { | |
make_path($self->inline_c_build_directory); | |
} | |
if (! -e $self->temp_dir) { | |
make_path($self->temp_dir); | |
} | |
Inline->bind(C => $c_source, | |
INC => $self->inline_c_inc, | |
AUTO_INCLUDE => $self->inline_c_auto_include, | |
LIBS => $self->inline_c_libs, | |
DIRECTORY => $self->inline_c_build_directory); | |
my (undef, $return_file_type) = split("/", $return_type); | |
my (undef, $filename) = tempfile($self->temp_file_template, | |
DIR => $self->temp_dir, | |
OPEN => 0, | |
SUFFIX => ".$return_file_type"); | |
my $tmpfile = __PACKAGE__::scale($image_path, $x_scale, $y_scale, $filename, $return_file_type); | |
my $data = read_file( $tmpfile ); | |
unlink $tmpfile; | |
return $data; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment