App-sitelenmute
view release on metacpan or search on metacpan
script/sitelen-mute view on Meta::CPAN
if ($t && $t->epoch()) {
$props->{date} = $t->strftime("%Y-%m-%d %H:%M");
$props->{stamp} = $ostamp = $t->epoch();
} else {
# no date available, cheat by using the previous timestamp
$props->{stamp} = $ostamp = $ostamp + 1;
}
# megapixels and average thereof
$props->{mp} = ($props->{ImageWidth} * $props->{ImageHeight} / 1e6);
$amp += $props->{mp};
}
$amp /= @files if @files;
# 2nd pass: produce output files
sub process_images {
my $p = Time::Progress->new(min => 0, max => scalar @_);
local $| = 1; # autoflush progress bar
my ($i, @result);
for (@_) {
print $p->report("\rImage file processing %20b ETA: %E", $i++);
push(@result, process_image($_));
}
say $p->report("\rImage file processing %20b done ", $i);
return \@result;
}
sub process_image {
my %props = %{$_[0]};
my $root = $props{root};
my $suffix = $props{suffix};
my $file = $props{file};
# derived file names
my $ofile = (splitpath($file))[2];
my $ffile = catfile('files', "$root.$suffix");
my $fbase = "$root.$ext";
my $fimg = catfile('imgs', $fbase);
my $fthumb = catfile('thumbs', $fbase);
my $fblur = catfile('blurs', $fbase);
my $absFout = catfile($absOut, $ffile);
my $absFtmp = catfile($absOut, "$ffile.tmp");
# copy source image, apply tranforms, set mode and file timestamp
copy_source_file($file, $absFout);
unless ($use_orig) {
if ($orient && $props{FileType} eq "JPEG" && ($props{Orientation} // 0)) {
sys("$exiftrancmd '$absFout' 2>/dev/null");
if (($props{Orientation} // 0) > 4) {
($props{ImageWidth}, $props{ImageHeight})
= ($props{ImageHeight}, $props{ImageWidth});
}
}
if ($jpegoptim && $props{FileType} eq "JPEG") {
sys('jpegoptim', '-q', $absFout);
} elsif ($pngoptim && $props{FileType} eq "PNG") {
sys('pngcrush', '-s', $absFout, $absFtmp);
rename($absFtmp, $absFout);
}
}
chmod($filemode, $absFout);
sys('touch', '-r', $file, $absFout);
# intermediate sRGB colorspace conversion
if ( !$sRGB || !defined($props{ProfileID})
|| ($props{ColorSpace} // 65535) == 1
|| ($props{DeviceModel} // '') eq 'sRGB') {
$absFtmp = $absFout;
} else {
sys('convert', '-quiet', $absFout, '-compress', 'LZW',
'-type', 'truecolor', "tiff:$absFtmp");
sys($tificccmd, '-t0', $absFtmp, "$absFtmp.tmp");
rename("$absFtmp.tmp", $absFtmp);
}
# generate main image
my @sfile = ($props{ImageWidth}, $props{ImageHeight});
my @simg = split m{\n+}, sys('convert', '-quiet', $absFtmp,
'-gamma', '0.454545',
'-geometry', "$maxfull[0]x$maxfull[1]>",
'-print', '%w\n%h',
'-gamma', '2.2',
'+profile', '!icc,*',
'-quality', $imgq, catfile($absOut, $fimg)
);
# face/center detection
my @center = (0.5, 0.5);
if ($facedet) {
my @f = split m{\n+}, sys("facedetect", "--best", "--center", catfile($absOut, $fimg));
for (@f) {
if (my @tmp = /(\d+) (\d+) (\d+) (\d+)/) {
@center = ($tmp[0] / $simg[0], $tmp[1] / $simg[1]);
last;
}
}
}
# thumbnail size
my $thumbrt;
if ($sfile[0] / $sfile[1] < $minthumb[0] / $minthumb[1]) {
$thumbrt = $minthumb[0] / $sfile[0];
} else {
$thumbrt = $minthumb[1] / $sfile[1];
}
my @sthumb = (max(int($sfile[0] * $thumbrt + 0.5), $minthumb[0]),
max(int($sfile[1] * $thumbrt + 0.5), $minthumb[1]));
my @mthumb = (min($maxthumb[0], $sthumb[0]),
min($maxthumb[1], $sthumb[1]));
# cropping window
my $dx = $sthumb[0] - $mthumb[0];
my $cx = pmin($dx, int($center[0] * $sthumb[0] - $sthumb[0] / 2 + $dx / 2));
my $dy = $sthumb[1] - $mthumb[1];
my $cy = pmin($dy, int($center[1] * $sthumb[1] - $sthumb[1] / 2 + $dy / 2));
sys('convert', '-quiet', $absFtmp,
'-gamma', '0.454545',
'-resize', "$sthumb[0]x$sthumb[1]!",
'-gravity', 'NorthWest',
'-crop', "$mthumb[0]x$mthumb[1]+$cx+$cy",
( run in 0.702 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )