App-ImageMagickUtils
view release on metacpan or search on metacpan
lib/App/ImageMagickUtils.pm view on Meta::CPAN
package App::ImageMagickUtils;
use 5.010001;
use strict;
use warnings;
use Log::ger;
use Perinci::Exporter;
our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2024-12-21'; # DATE
our $DIST = 'App-ImageMagickUtils'; # DIST
our $VERSION = '0.024'; # VERSION
our %SPEC;
$SPEC{':package'} = {
v => 1.1,
summary => 'Utilities related to ImageMagick',
};
our %argspec0plus_files = (
files => {
'x.name.is_plural' => 1,
'x.name.singular' => 'file',
schema => ['array*' => of => 'filename*'],
req => 1,
pos => 0,
slurpy => 1,
},
);
our %argspec0plus_files__comp_png = (
files => {
'x.name.is_plural' => 1,
'x.name.singular' => 'file',
schema => ['array*' => of => 'filename*'],
'x.completion' => [filename => {file_ext_filter=>'png'}],
req => 1,
pos => 0,
slurpy => 1,
},
);
our %argspec0plus_files__comp_jpg = (
files => {
'x.name.is_plural' => 1,
'x.name.singular' => 'file',
schema => ['array*' => of => 'filename*'],
'x.completion' => [filename => {file_ext_filter=>qr/^(jpe?g)$/i}],
req => 1,
pos => 0,
slurpy => 1,
},
);
our %argspec0plus_files__comp_pdf = (
files => {
'x.name.is_plural' => 1,
'x.name.singular' => 'file',
schema => ['array*' => of => 'filename*'],
'x.completion' => [filename => {file_ext_filter=>'pdf'}],
req => 1,
pos => 0,
slurpy => 1,
},
);
our %argspecs_delete = (
delete_original => {
summary => 'Delete (unlink) the original file after downsizing',
schema => 'bool*',
description => <<'MARKDOWN',
See also the `trash_original` option.
MARKDOWN
cmdline_aliases => {D=>{}},
},
trash_original => {
summary => 'Trash the original file after downsizing',
schema => 'bool*',
description => <<'MARKDOWN',
This option uses the <pm:File::Trash::FreeDesktop> module to do the trashing.
Compared to deletion, with this option you can still restore the trashed
original files from the Trash directory.
See also the `delete_original` option.
MARKDOWN
cmdline_aliases => {T=>{}},
},
);
our %argspecopt_quality = (
quality => {
summary => 'Quality setting (for JPEG/PNG), 1 (best compression, worst quality) to 100 (least compression, best quality)',
lib/App/ImageMagickUtils.pm view on Meta::CPAN
my $ext = $downsized ? ".$downsize_to-q$q.jpg" : ".q$q.jpg";
$output_file =~ s/(\.\w{3,4})?\z/($1 eq ".jpg" ? "" : $1) . $ext/e;
push @convert_args, (
$output_file,
);
if ($args{-dry_run}) {
log_info "[DRY-RUN] Running $convert_path with args %s ...", \@convert_args;
$num_success++;
next FILE;
}
log_info "Running $convert_path with args %s ...", \@convert_args;
IPC::System::Options::system(
$convert_path, @convert_args,
);
if ($?) {
my ($exit_code, $signal, $core_dump) = ($? < 0 ? $? : $? >> 8, $? & 127, $? & 128);
log_error "convert for $file failed: exit_code=$exit_code, signal=$signal, core_dump=$core_dump";
} else {
if ($args{trash_original}) {
require File::Trash::FreeDesktop;
$trash //= File::Trash::FreeDesktop->new;
log_info "Trashing original file %s ...", $file;
# will die upon failure, currently we don't trap
$trash->trash($file);
} elsif ($args{delete_original}) {
# currently we ignore the results
log_info "Deleting original file %s ...", $file;
unlink $file;
}
$num_success++;
}
}
$num_success == 0 ? [500, "All files failed"] : [200];
}
$SPEC{convert_image_to} = {
v => 1.1,
summary => 'Convert images using ImageMagick\'s \'convert\' utility, with multiple file support and automatic output naming',
description => <<'MARKDOWN',
This is a simple wrapper to ImageMagick's `convert` utility to let you process
multiple files using a single command:
% convert-image-to --to pdf *.jpg
is basically equivalent to:
% for f in *.jpg; do convert "$f" "$f.pdf"; done
MARKDOWN
args => {
%argspec0plus_files,
%argspecopt_quality,
to => {
schema => ['str*', match=>qr/\A\w+\z/],
req => 1,
examples => [qw/pdf jpg png/], # for tab completion
},
%argspecs_delete,
},
#features => {
# dry_run => 1,
#},
deps => {
prog => 'convert',
},
examples => [
],
};
sub convert_image_to {
require IPC::System::Options;
require Perinci::Object;
require Process::Status;
my %args = @_;
my $to = $args{to} or return [400, "Please specify target format in `to`"];
my $envres = Perinci::Object::envresmulti();
my $trash;
for my $file (@{$args{files}}) {
log_info "Processing file %s ...", $file;
IPC::System::Options::system(
{log=>1},
"convert", ($args{quality} ? ("-quality", $args{quality}) : ()), $file, "$file.$to",
);
my $ps = Process::Status->new;
if ($ps->is_success) {
$envres->add_result(200, "OK", {item_id=>$file});
if ($args{trash_original}) {
require File::Trash::FreeDesktop;
$trash //= File::Trash::FreeDesktop->new;
log_info "Trashing original file %s ...", $file;
# will die upon failure, currently we don't trap
$trash->trash($file);
} elsif ($args{delete_original}) {
# currently we ignore the result of deletion
log_info "Deleting original file %s ...", $file;
unlink $file;
}
} else {
$envres->add_result(500, "Failed (exit code ".$ps->exitstatus.")", {item_id=>$file});
}
}
$envres->as_struct;
}
$SPEC{convert_image_to_pdf} = {
v => 1.1,
summary => 'Convert images to PDF using ImageMagick\'s \'convert\' utility',
description => <<'MARKDOWN',
This is a wrapper to `convert-image-to`, with `--to` set to `pdf`:
% convert-image-to-pdf *.jpg
is equivalent to:
% convert-image-to --to pdf *.jpg
which in turn is equivalent to:
% for f in *.jpg; do convert "$f" "$f.pdf"; done
MARKDOWN
args => {
%argspec0plus_files,
%argspecs_delete,
},
#features => {
# dry_run => 1,
#},
deps => {
prog => 'convert',
},
examples => [
],
};
sub convert_image_to_pdf {
my %args = @_;
convert_image_to(%args, to=>'pdf');
}
$SPEC{convert_image_to_jpg} = {
v => 1.1,
summary => 'Convert images to JPG using ImageMagick\'s \'convert\' utility',
description => <<'MARKDOWN',
This is a wrapper to `convert-image-to`, with `--to` set to `jpg`:
% convert-image-to-pdf *.png
is equivalent to:
% convert-image-to --to jpg *.png
which in turn is equivalent to:
% for f in *.png; do convert "$f" "$f.jpg"; done
MARKDOWN
args => {
%argspec0plus_files,
%argspecopt_quality,
%argspecs_delete,
},
#features => {
# dry_run => 1,
#},
deps => {
prog => 'convert',
},
examples => [
],
};
sub convert_image_to_jpg {
my %args = @_;
convert_image_to(%args, to=>'jpg');
}
$SPEC{convert_image_to_png} = {
v => 1.1,
summary => 'Convert images to JPG using ImageMagick\'s \'convert\' utility',
description => <<'MARKDOWN',
This is a wrapper to `convert-image-to`, with `--to` set to `png`:
% convert-image-to-png *.jpg
is equivalent to:
% convert-image-to --to png *.jpg
which in turn is equivalent to:
% for f in *.jpg; do convert "$f" "$f.png"; done
MARKDOWN
args => {
%argspec0plus_files,
%argspecopt_quality,
%argspecs_delete,
},
#features => {
# dry_run => 1,
#},
deps => {
prog => 'convert',
},
examples => [
],
};
sub convert_image_to_png {
my %args = @_;
convert_image_to(%args, to=>'png');
}
1;
# ABSTRACT: Utilities related to ImageMagick
__END__
=pod
=encoding UTF-8
=head1 NAME
App::ImageMagickUtils - Utilities related to ImageMagick
=head1 VERSION
This document describes version 0.024 of App::ImageMagickUtils (from Perl distribution App-ImageMagickUtils), released on 2024-12-21.
=head1 DESCRIPTION
This distribution includes the following CLI utilities related to ImageMagick:
=over
=item 1. L<calc-image-resized-size>
=item 2. L<convert-image-to>
=item 3. L<convert-image-to-jpg>
=item 4. L<convert-image-to-pdf>
=item 5. L<convert-image-to-png>
=item 6. L<downsize-image>
=item 7. L<image-resize-notation-to-human>
=item 8. L<img2jpg>
=item 9. L<img2pdf>
=item 10. L<img2png>
=item 11. L<jpg2png>
=item 12. L<png2jpg>
=back
=head1 FUNCTIONS
=head2 convert_image_to
Usage:
convert_image_to(%args) -> [$status_code, $reason, $payload, \%result_meta]
Convert images using ImageMagick's 'convert' utility, with multiple file support and automatic output naming.
This is a simple wrapper to ImageMagick's C<convert> utility to let you process
multiple files using a single command:
% convert-image-to --to pdf *.jpg
is basically equivalent to:
% for f in *.jpg; do convert "$f" "$f.pdf"; done
This function is not exported.
Arguments ('*' denotes required arguments):
=over 4
=item * B<delete_original> => I<bool>
Delete (unlink) the original file after downsizing.
See also the C<trash_original> option.
=item * B<files>* => I<array[filename]>
(No description)
=item * B<quality> => I<int> (default: 92)
Quality setting (for JPEGE<sol>PNG), 1 (best compression, worst quality) to 100 (least compression, best quality).
=item * B<to>* => I<str>
(No description)
=item * B<trash_original> => I<bool>
Trash the original file after downsizing.
This option uses the L<File::Trash::FreeDesktop> module to do the trashing.
Compared to deletion, with this option you can still restore the trashed
original files from the Trash directory.
See also the C<delete_original> option.
=back
Returns an enveloped result (an array).
First element ($status_code) is an integer containing HTTP-like status code
(200 means OK, 4xx caller error, 5xx function error). Second element
($reason) is a string containing error message, or something like "OK" if status is
200. Third element ($payload) is the actual result, but usually not present when enveloped result is an error response ($status_code is not 2xx). Fourth
element (%result_meta) is called result metadata and is optional, a hash
that contains extra information, much like how HTTP response headers provide additional metadata.
Return value: (any)
=head2 convert_image_to_jpg
Usage:
convert_image_to_jpg(%args) -> [$status_code, $reason, $payload, \%result_meta]
Convert images to JPG using ImageMagick's 'convert' utility.
This is a wrapper to C<convert-image-to>, with C<--to> set to C<jpg>:
% convert-image-to-pdf *.png
is equivalent to:
% convert-image-to --to jpg *.png
which in turn is equivalent to:
% for f in *.png; do convert "$f" "$f.jpg"; done
This function is not exported.
Arguments ('*' denotes required arguments):
=over 4
=item * B<delete_original> => I<bool>
Delete (unlink) the original file after downsizing.
See also the C<trash_original> option.
=item * B<files>* => I<array[filename]>
(No description)
=item * B<quality> => I<int> (default: 92)
Quality setting (for JPEGE<sol>PNG), 1 (best compression, worst quality) to 100 (least compression, best quality).
=item * B<trash_original> => I<bool>
Trash the original file after downsizing.
This option uses the L<File::Trash::FreeDesktop> module to do the trashing.
Compared to deletion, with this option you can still restore the trashed
original files from the Trash directory.
See also the C<delete_original> option.
=back
Returns an enveloped result (an array).
First element ($status_code) is an integer containing HTTP-like status code
(200 means OK, 4xx caller error, 5xx function error). Second element
($reason) is a string containing error message, or something like "OK" if status is
200. Third element ($payload) is the actual result, but usually not present when enveloped result is an error response ($status_code is not 2xx). Fourth
element (%result_meta) is called result metadata and is optional, a hash
that contains extra information, much like how HTTP response headers provide additional metadata.
Return value: (any)
=head2 convert_image_to_pdf
Usage:
convert_image_to_pdf(%args) -> [$status_code, $reason, $payload, \%result_meta]
Convert images to PDF using ImageMagick's 'convert' utility.
This is a wrapper to C<convert-image-to>, with C<--to> set to C<pdf>:
% convert-image-to-pdf *.jpg
is equivalent to:
% convert-image-to --to pdf *.jpg
which in turn is equivalent to:
% for f in *.jpg; do convert "$f" "$f.pdf"; done
This function is not exported.
Arguments ('*' denotes required arguments):
=over 4
=item * B<delete_original> => I<bool>
Delete (unlink) the original file after downsizing.
See also the C<trash_original> option.
=item * B<files>* => I<array[filename]>
(No description)
=item * B<trash_original> => I<bool>
Trash the original file after downsizing.
This option uses the L<File::Trash::FreeDesktop> module to do the trashing.
Compared to deletion, with this option you can still restore the trashed
original files from the Trash directory.
See also the C<delete_original> option.
=back
Returns an enveloped result (an array).
First element ($status_code) is an integer containing HTTP-like status code
(200 means OK, 4xx caller error, 5xx function error). Second element
($reason) is a string containing error message, or something like "OK" if status is
200. Third element ($payload) is the actual result, but usually not present when enveloped result is an error response ($status_code is not 2xx). Fourth
element (%result_meta) is called result metadata and is optional, a hash
that contains extra information, much like how HTTP response headers provide additional metadata.
Return value: (any)
=head2 convert_image_to_png
Usage:
convert_image_to_png(%args) -> [$status_code, $reason, $payload, \%result_meta]
Convert images to JPG using ImageMagick's 'convert' utility.
This is a wrapper to C<convert-image-to>, with C<--to> set to C<png>:
% convert-image-to-png *.jpg
is equivalent to:
% convert-image-to --to png *.jpg
which in turn is equivalent to:
% for f in *.jpg; do convert "$f" "$f.png"; done
This function is not exported.
Arguments ('*' denotes required arguments):
=over 4
=item * B<delete_original> => I<bool>
Delete (unlink) the original file after downsizing.
See also the C<trash_original> option.
=item * B<files>* => I<array[filename]>
(No description)
=item * B<quality> => I<int> (default: 92)
Quality setting (for JPEGE<sol>PNG), 1 (best compression, worst quality) to 100 (least compression, best quality).
=item * B<trash_original> => I<bool>
Trash the original file after downsizing.
This option uses the L<File::Trash::FreeDesktop> module to do the trashing.
Compared to deletion, with this option you can still restore the trashed
original files from the Trash directory.
See also the C<delete_original> option.
=back
Returns an enveloped result (an array).
First element ($status_code) is an integer containing HTTP-like status code
(200 means OK, 4xx caller error, 5xx function error). Second element
($reason) is a string containing error message, or something like "OK" if status is
200. Third element ($payload) is the actual result, but usually not present when enveloped result is an error response ($status_code is not 2xx). Fourth
element (%result_meta) is called result metadata and is optional, a hash
that contains extra information, much like how HTTP response headers provide additional metadata.
Return value: (any)
=head2 downsize_image
Usage:
downsize_image(%args) -> [$status_code, $reason, $payload, \%result_meta]
Reduce image size, by default via compressing to JPEG quality 40 and downsizing to 1024p.
This utility uses L<convert> utility to compress an image into JPEG with
default quality of 40 and downsized to 1024p (shortest side to 1024px).
Output filenames are:
( run in 2.286 seconds using v1.01-cache-2.11-cpan-df04353d9ac )