From 81dc6c8c1a362ed6380f7a56390ac4a564ae29d6 Mon Sep 17 00:00:00 2001 From: profiteroles Date: Tue, 7 May 2019 01:54:27 -0700 Subject: [PATCH] 0.8.3 --- leaf.php | 246 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 220 insertions(+), 26 deletions(-) diff --git a/leaf.php b/leaf.php index 4075ada..2ca6f56 100644 --- a/leaf.php +++ b/leaf.php @@ -1,7 +1,8 @@ 2) { return chop($argv[count($argv)-1], "/")."/"; + } elseif ($query == "levels" && isset($opt['levels'])) { + return levels_ps_to_imgk($opt['levels']); } elseif (isset($opt[$query])) { return $opt[$query]; } else { @@ -158,6 +177,7 @@ $help = "Leaf $version USAGE: leaf [mode] [-options] directory Modes: +build combine images into a pdf with img2pdf clean remove scratch files crop define EXIF crop values using template files -crops= (6) specify how many files to use @@ -168,11 +188,17 @@ deskew detect rotation angles -contrast= (20) levels attenuation -size= (2200) dmap size in pixels -nomap don't use dmaps +despine remove shadow from spine + -target= only process pages with spine similar to the spine of this target file + -levels= levels for overlay (ex. \"0-253,0-255,0-2\") + -width= (300) spine width in pixels + -q=<0-100> (auto) jpeg quality, default read from source or 95 divide wrapper for imagemagick Divide_Src -map= specify brightness file - -adjust= levels adjustment (ex. \"0%,98%,.9\") + -levels= photoshop levels adjustment (ex. \"0-253,0-255,0-2\") -q= (95) quality out of 100 -pages map file is for LR rotated pages + -mix=<0-100> percentage mix with original (90% = mostly og) dupes Find duplicate images using computed PHASH on thumbnails -threshold= (10) match threshold -walk= (5) comparison scope (compare n image to n, n+1, n+2, etc) @@ -182,10 +208,9 @@ generate create final jpg images for pdf creation -pixels= scale to x pixels on longest side -inches= set dpi to x inches on longest side -q=<0-100> (90) jpeg quality - -adjust= levels adjustment (ex. \"0%,98%,.9\") + -levels= photoshop levels adjustment (ex. \"0-253,0-255,0-2\") -px= png size multiplier - -padjust= png levels adjustment (otherwise calculated from adjust) -makepdf combine images into a pdf with img2pdf + -plevels= png levels adjustment (otherwise calculated from adjust) match move files and set crop values to match source dir -source= read FROM dir profile apply xmp profile to images (requires exiv2 > 0.25) @@ -208,6 +233,143 @@ strip strip exif crop values from images with exiftool echo $help; fin(); +//////////////////////////////////////////////////////////////////////////////////////////////// +// Note: Brightness_table +////////////////////// +} elseif (args("app") == "brightness_table") { +echo Welcome("Display brightness values for a directory of images"); +///////////////////////////////////////////////////////////////////////// + +$files = glob(args("dir")."*.*"); +foreach ($files as $file) { + echo $file.": ".filter_var(shell_exec("convert ".$file." -colorspace Gray -format \"%[fx:quantumrange*image.mean]\" info:"),FILTER_SANITIZE_NUMBER_INT)."\n"; + } + +fin(); + +//////////////////////////////////////////////////////////////////////////////////////////////// +// Note: Despine +////////////////////// +} elseif (args("app") == "despine") { +echo Welcome("Remove spine on white pages"); +///////////////////////////////////////////////////////////////////////// + +$threshold = 190; +$default_quality = 95; +$dest = rtrim(args("dir"), '/')."_despined"; + +if (count(glob($dest."/*.*"))) { + msg("Files already exist in ".$dest.". Move to trash?",2); + exec("/opt/local/bin/trash -a ".$dest); + mkdir($dest); + } elseif (!is_dir($dest)) { + mkdir($dest); + } + +if (args("width")) { + $swidth = args("width"); + } else { + $swidth = 240; + } + +if (args("levels")) { + $adjust = args("levels"); + } else { + $adjust = levels_ps_to_imgk("0,250,1"); + } + +//if (!args("target") || !is_file(args("target"))) { +// msg("Specify a target file to match spine",1); +// } else { +// $target = args("target"); +// } + +//$ext = pathinfo($target,PATHINFO_EXTENSION); +//$tspine_left = "scratch/".basename($target, ".".$ext)."_spineleft.".$ext; +//$tspine_right = "scratch/".basename($target, ".".$ext)."_spineright.".$ext; +//list ($width, $height) = getimagesize($target); +//$even = 0; +//if (substr(basename($target), 0, 3) % 2 == 0) { +// $geo = "+".($width-$swidth)."+0"; +// $cropsize = $swidth."x".$height; +// $crop = $cropsize.$geo; +// $even = 1; +// } else { +// $geo = "+0+0"; +// $cropsize = $swidth."x".$height; +// $crop = $cropsize.$geo; +// } +// +//if ($even) { +// exec("convert ".$target." -crop ".$crop." -flop ".$tspine_left); +// exec("convert ".$target." -crop ".$crop." ".$tspine_right); +// } else { +// exec("convert ".$target." -crop ".$crop." ".$tspine_left); +// exec("convert ".$target." -crop ".$crop." -flop ".$tspine_right); +// } + +$files = glob(args("dir")."[0-9][0-9][0-9]-*"); + +msg("Comparing spines"); + +foreach ($files as $file) { + $ext = pathinfo($file,PATHINFO_EXTENSION); + list ($width, $height) = getimagesize($file); + if (substr(basename($file), 0, 3) % 2 == 0) { + $geo = "+".($width-$swidth)."+0"; + $cropsize = $swidth."x".$height; + $crop = $cropsize.$geo; +// $mytspine = $tspine_right; + } else { + $geo = "+0+0"; + $cropsize = $swidth."x".$height; + $crop = $cropsize.$geo; +// $mytspine = $tspine_left; + } +// $filespine = "/tmp/".basename($file,$ext)."-spine.".$ext; +// if (!file_exists($filespine)) { +// exec("convert ".$file." -auto-orient -crop ".$crop." ".$filespine); +// } + +// $distance = chop(shell_exec("compare -metric phash ".$mytspine." ".$filespine." /tmp/diffimage 2>&1")); + +// if ($distance < $threshold) { +// $print_distance = bashcolor($distance,"green"); +// } else { +// $print_distance = $distance; +// } +// msg("Comparing ".$mytspine." with ".$filespine.": ".$print_distance); + + if (args("q")) { + $quality = args("q"); + } elseif (strtolower($ext) == "jpg") { + $quality = chop(shell_exec("identify -format '%Q' ".$file)); + } else { + $quality = $default_quality; + } + + //if ($distance < $threshold) { + $msg = $file." matched, despining..."; + $cmd = "convert ".$file." \( ".$file." -auto-orient -crop ".$crop." -colorspace gray -level ".$adjust." \) -auto-orient -geometry ".$geo." -compose Divide_Src -composite -quality ".$quality." ".$dest."/".basename($file); + if (args("mix")) { + $pass1 = str_replace("convert", "convert \(", $cmd); + $pass2 = str_replace("-composite", "-composite \) ".$file." -auto-orient -compose dissolve -define compose:args=".args("mix")." -composite", $pass1); + $cmd = $pass2; + } + //} else { + //$msg = $file." "; + //$cmd = "true"; + //} + + $thread[] = array($msg, $cmd); + } + +echo "\n\n"; +msg("Beginning multithreaded convert with ".$xt." threads"); +multiexec($thread,$xt); + +fin(); + //////////////////////////////////////////////////////////////////////////////////////////////// // Note: Match ////////////////////// @@ -221,6 +383,9 @@ if (!$files) { msg("No valid files in source dir!",1); } +$i = 0; +$ix = 0; + foreach ($files as $file) { $ext = pathinfo($file,PATHINFO_EXTENSION); $key = substr(basename($file), 0, 3); @@ -231,7 +396,10 @@ foreach ($files as $file) { if (basename($file,$ext) != basename($dest,$dparts['extension'])) { $newdest = $dparts['dirname']."/".$key."-".$dparts['basename']; msg("Moving ".$dest." to ".$newdest); - //rename($dest,$newdest); + rename($dest,$newdest); + $i++; + } else { + $newdest = $dest; } $parts = chop(shell_exec("exiftool -s -s -s -XMP-crs:CropTop -XMP-crs:CropRight -XMP-crs:CropLeft -XMP-crs:CropBottom -XMP-crs:CropAngle ".$file." 2>&1")); @list($top, $right, $left, $bottom, $angle) = explode("\n", $parts); @@ -243,7 +411,8 @@ foreach ($files as $file) { $info .= " Bottom: ".bashcolor($bottom,"green"); $info .= " Angle: ".bashcolor($angle,"green"); msg($info); - //exec("exiftool -overwrite_original -XMP-crs:HasCrop=1 -XMP-crs:AlreadyApplied=0 -XMP-crs:CropTop=".$top." -XMP-crs:CropRight=".$right." -XMP-crs:CropLeft=".$left." -XMP-crs:CropBottom=".$bottom." -XMP-crs:CropAngle=".$angle." ".$file); + exec("exiftool -overwrite_original -XMP-crs:HasCrop=1 -XMP-crs:AlreadyApplied=0 -XMP-crs:CropTop=".$top." -XMP-crs:CropRight=".$right." -XMP-crs:CropLeft=".$left." -XMP-crs:CropBottom=".$bottom." -XMP-crs:CropAngle=".$angle." ".$newdest); + $ix++; } else { msg("Source file ".$file." does not contain crop information"); } @@ -253,6 +422,11 @@ foreach ($files as $file) { } +echo "\n"; + +msg("Moved ".$i." files"); +msg("Tagged ".$ix." files"); + fin(); //////////////////////////////////////////////////////////////////////////////////////////////// @@ -410,9 +584,9 @@ foreach ($jpg as $parts) { } - if (args("adjust")) { - $msg .= " (".args("adjust").")"; - $cmd .= "-level ".args("adjust")." "; + if (args("levels")) { + $msg .= " (".args("levels").")"; + $cmd .= "-level ".args("levels")." "; } $msg .= " [Q=".$quality."]"; @@ -441,8 +615,8 @@ if (isset($bitmap)) { $msg = "Processing bitmap page ".$file." @ ".$pngdims."!"; $cmd = "convert -resize ".$pngdims."\! "; - if (args("adjust")) { - $adjust = args("adjust"); + if (args("levels")) { + $adjust = args("levels"); } else { $adjust = "0%,100%,1"; } @@ -452,8 +626,8 @@ if (isset($bitmap)) { $white = rtrim($parts[1],"%"); $gamma = $parts[2]; - if (args("padjust")) { - $radjust = args("padjust"); + if (args("plevels")) { + $radjust = args("plevels"); } else { $radjust = ($black+60)."%".",".($white-15)."%".",".($gamma-.7); } @@ -564,7 +738,7 @@ foreach ($files as $file) { if (args("q")) { $quality = args("q"); } elseif (strtolower($ext) == "jpg") { - $quality = @exec("identify -format '%Q' ".$file); + $quality = chop(shell_exec("identify -format '%Q' ".$file)); } else { $quality = $default_quality; } @@ -1046,9 +1220,9 @@ foreach ($files as $file) { fin(); //////////////////////////////////////////////////////////////////////////////////////////////// -// Note: Makepdf +// Note: Build ////////////////////// -} elseif (args("app") == "makepdf") { +} elseif (args("app") == "build") { echo Welcome("Combine finished images into a pdf with python img2pdf"); ///////////////////////////////////////////////////////////////////////// @@ -1144,6 +1318,11 @@ if (!args("map")) { $map = args("map"); } +if (args("mpush")) { + $map = basename(args("map"),".JPG")."-pushed.tif"; + @exec("convert -level ".levels_ps_to_imgk(args("mpush"))." ".args("map")." ".$map); + } + $dest = rtrim(args("dir"), '/')."_divided"; if (count(glob($dest."/*.*"))) { @@ -1164,8 +1343,9 @@ if ($pages) { $ext = pathinfo($map, PATHINFO_EXTENSION); $mapleft = "scratch/".str_replace(".".$ext, "_left.".$ext, $map); $mapright = "scratch/".str_replace(".".$ext, "_right.".$ext, $map); - exec("convert -rotate 90 -quality 95 ".$map." ".$mapleft); - exec("convert -rotate 270 -quality 95 ".$map." ".$mapright); + //@exec("convert -rotate 90 -quality 95 ".$map." ".$mapleft." 2>&1"); + @exec("convert -rotate 90 -flip -quality 95 ".$map." ".$mapleft." 2>&1"); + @exec("convert -rotate 270 -quality 95 ".$map." ".$mapright." 2>&1"); } echo "Building threads: "; @@ -1174,7 +1354,7 @@ $thread = array(); foreach ($files as $file) { $msg = "Dividing ".$file." with ".$map.", Q=".$quality; - $cmd = "convert ".$file." "; + $cmd = "convert ".$file; $output = $dest."/".basename($file); if ($pages) { @@ -1198,7 +1378,7 @@ foreach ($files as $file) { list ($twidth, $theight) = getimagesize($file); if ($width != $twidth || $height != $theight) { $tmap = $use."'[".$twidth."x".$theight."!]'"; - $msg .= " (resize map) "; + $msg .= " (resize map)"; } else { $tmap = $use; } @@ -1209,16 +1389,30 @@ foreach ($files as $file) { } - $cmd .= $tmap." -compose Divide_Src -composite -quality ".$quality." "; - - if (args("adjust")) { - $msg .= " (".args("adjust").") "; - $cmd .= "-level ".args("adjust")." "; + if (args("blur")) { + $msg .= " (".args("blur").")"; + $overlay = "\( ".$tmap." -blur ".args("blur")." \)"; + } else { + $overlay = $tmap; } + + $cmd .= " ".$overlay." -compose Divide_Src -composite -quality ".$quality." "; + + if (args("levels")) { + $msg .= " (".args("levels").") "; + $cmd .= "-level ".args("levels")." "; + } $cmd .= $output; echo "."; + + if (args("mix")) { + $pass1 = str_replace("convert", "convert \(", $cmd); + $pass2 = str_replace("-composite", "-composite \) ".$file." -compose dissolve -define compose:args=".args("mix")." -composite", $pass1); + $cmd = $pass2; + } + $thread[] = array($msg, $cmd); }