0.8.4
This commit is contained in:
160
leaf.php
160
leaf.php
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Leaf - Tools for Book Scans
|
// Leaf - Tools for Book Scans
|
||||||
$version = "0.8.3";
|
$version = "0.8.4";
|
||||||
$debug = 0;
|
$debug = 1;
|
||||||
$time_start = microtime(true);
|
$time_start = microtime(true);
|
||||||
date_default_timezone_set("America/Los_Angeles");
|
date_default_timezone_set("America/Los_Angeles");
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ function multiexec($thread, $x, $null = true) {
|
|||||||
if ($debug) {
|
if ($debug) {
|
||||||
echo "\n\n".$exec."\n\n";
|
echo "\n\n".$exec."\n\n";
|
||||||
}
|
}
|
||||||
exec($exec);
|
@exec($exec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,14 +188,19 @@ deskew detect rotation angles
|
|||||||
-contrast=<num> (20) levels attenuation
|
-contrast=<num> (20) levels attenuation
|
||||||
-size=<num> (2200) dmap size in pixels
|
-size=<num> (2200) dmap size in pixels
|
||||||
-nomap don't use dmaps
|
-nomap don't use dmaps
|
||||||
|
depaper divide page with itself using mask (better despine)
|
||||||
|
-mask=<file> mask file for spine-left image
|
||||||
|
-mpush=<levels> levels for divide map (ex. \"0-253,0-255,0-2\")
|
||||||
|
-mix=<0-100> percentage mix with original (90% = mostly og)
|
||||||
despine remove shadow from spine
|
despine remove shadow from spine
|
||||||
-target=<file> only process pages with spine similar to the spine of this target file
|
|
||||||
-levels=<params> levels for overlay (ex. \"0-253,0-255,0-2\")
|
-levels=<params> levels for overlay (ex. \"0-253,0-255,0-2\")
|
||||||
-width=<pixels> (300) spine width in pixels
|
-width=<pixels> (300) spine width in pixels
|
||||||
-q=<0-100> (auto) jpeg quality, default read from source or 95
|
-q=<0-100> (auto) jpeg quality, default read from source or 95
|
||||||
divide wrapper for imagemagick Divide_Src
|
divide wrapper for imagemagick Divide_Src
|
||||||
-map=<file> specify brightness file
|
-map=<file> specify brightness file
|
||||||
-levels=<params> photoshop levels adjustment (ex. \"0-253,0-255,0-2\")
|
-mpush=<levels> levels for map (ex. \"0-253,0-255,0-2\") or \"auto\"
|
||||||
|
-blur=<pixels> apply in-place blur to map (slow/dumb)
|
||||||
|
-levels=<params> levels adjustment for resulting image (ex. \"0-253,0-255,0-2\")
|
||||||
-q=<quality> (95) quality out of 100
|
-q=<quality> (95) quality out of 100
|
||||||
-pages map file is for LR rotated pages
|
-pages map file is for LR rotated pages
|
||||||
-mix=<0-100> percentage mix with original (90% = mostly og)
|
-mix=<0-100> percentage mix with original (90% = mostly og)
|
||||||
@@ -247,6 +252,46 @@ foreach ($files as $file) {
|
|||||||
|
|
||||||
fin();
|
fin();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Note: Depaper
|
||||||
|
//////////////////////
|
||||||
|
} elseif (args("app") == "depaper") {
|
||||||
|
echo Welcome("Divide with self using mask");
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
$dest = rtrim(args("dir"), '/')."_depaper";
|
||||||
|
|
||||||
|
if (!file_exists(args("mask"))) {
|
||||||
|
msg("Can't open mask",1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = glob(args("dir")."*.*");
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$ext = pathinfo($file,PATHINFO_EXTENSION);
|
||||||
|
$result = $dest."/".basename($file);
|
||||||
|
list ($width, $height) = getimagesize($file);
|
||||||
|
if (substr(basename($file), 0, 3) % 2 == 0) {
|
||||||
|
$cmd = "convert test.jpg \( ".$file." \( ".args("mask")."[".$width."x".$height."] -rotate 180 \) -alpha Off -compose CopyOpacity -composite \) -compose Over -composite ".$result;
|
||||||
|
} else {
|
||||||
|
$cmd = "convert test.jpg \( ".$file." ".args("mask")."[".$width."x".$height."] -alpha Off -compose CopyOpacity -composite \) -compose Over -composite ".$result;
|
||||||
|
}
|
||||||
|
$msg = "Converting ".$file;
|
||||||
|
$thread[] = array($msg, $cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg("Beginning multithreaded convert with ".$xt." threads");
|
||||||
|
multiexec($thread,$xt);
|
||||||
|
|
||||||
|
fin();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Note: Despine
|
// Note: Despine
|
||||||
//////////////////////
|
//////////////////////
|
||||||
@@ -278,36 +323,6 @@ if (args("levels")) {
|
|||||||
$adjust = levels_ps_to_imgk("0,250,1");
|
$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]-*");
|
$files = glob(args("dir")."[0-9][0-9][0-9]-*");
|
||||||
|
|
||||||
msg("Comparing spines");
|
msg("Comparing spines");
|
||||||
@@ -319,26 +334,11 @@ foreach ($files as $file) {
|
|||||||
$geo = "+".($width-$swidth)."+0";
|
$geo = "+".($width-$swidth)."+0";
|
||||||
$cropsize = $swidth."x".$height;
|
$cropsize = $swidth."x".$height;
|
||||||
$crop = $cropsize.$geo;
|
$crop = $cropsize.$geo;
|
||||||
// $mytspine = $tspine_right;
|
|
||||||
} else {
|
} else {
|
||||||
$geo = "+0+0";
|
$geo = "+0+0";
|
||||||
$cropsize = $swidth."x".$height;
|
$cropsize = $swidth."x".$height;
|
||||||
$crop = $cropsize.$geo;
|
$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")) {
|
if (args("q")) {
|
||||||
$quality = args("q");
|
$quality = args("q");
|
||||||
@@ -348,7 +348,7 @@ foreach ($files as $file) {
|
|||||||
$quality = $default_quality;
|
$quality = $default_quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if ($distance < $threshold) {
|
|
||||||
$msg = $file." matched, despining...";
|
$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);
|
$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")) {
|
if (args("mix")) {
|
||||||
@@ -356,10 +356,6 @@ foreach ($files as $file) {
|
|||||||
$pass2 = str_replace("-composite", "-composite \) ".$file." -auto-orient -compose dissolve -define compose:args=".args("mix")." -composite", $pass1);
|
$pass2 = str_replace("-composite", "-composite \) ".$file." -auto-orient -compose dissolve -define compose:args=".args("mix")." -composite", $pass1);
|
||||||
$cmd = $pass2;
|
$cmd = $pass2;
|
||||||
}
|
}
|
||||||
//} else {
|
|
||||||
//$msg = $file." <skip>";
|
|
||||||
//$cmd = "true";
|
|
||||||
//}
|
|
||||||
|
|
||||||
$thread[] = array($msg, $cmd);
|
$thread[] = array($msg, $cmd);
|
||||||
}
|
}
|
||||||
@@ -694,11 +690,14 @@ $hough = "9x9+200";
|
|||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
$ext = pathinfo($file,PATHINFO_EXTENSION);
|
$ext = pathinfo($file,PATHINFO_EXTENSION);
|
||||||
$output = $dest."/".basename($file,$ext)."jpg";
|
$output = $dest."/".basename($file,$ext)."jpg";
|
||||||
$msg = "Detecting edges in ".$file;
|
$msg = "Creating hough composite from ".$file;
|
||||||
$cmd = "convert ".$file."[".$size."x".$size."] -auto-orient \( +clone -canny ".$canny." -write /tmp/".basename($file)."_canny.png ";
|
$cmd = "convert ".$file."[".$size."x".$size."] -auto-orient \( +clone -canny ".$canny." -write /tmp/".basename($file)."_canny.png ";
|
||||||
$cmd .= "-background none -fill red -stroke red -strokewidth 1 -hough-lines ".$hough." -write /tmp/".basename($file)."_lines.png \) ";
|
$cmd .= "-background none -fill red -stroke red -strokewidth 1 -hough-lines ".$hough." -write /tmp/".basename($file)."_lines.png \) ";
|
||||||
$cmd .= "-composite ".$output;
|
$cmd .= "-composite ".$output;
|
||||||
$thread[] = array($msg, $cmd);
|
$thread[] = array($msg, $cmd);
|
||||||
|
$msg = "Creating MVG file from ".$file;
|
||||||
|
$cmd = "convert /tmp/".basename($file)."_canny.png -hough-lines ".$hough." ".$output.".mvg";
|
||||||
|
$thread[] = array($msg, $cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg("Beginning multithreaded convert with ".$xt." threads");
|
msg("Beginning multithreaded convert with ".$xt." threads");
|
||||||
@@ -1303,24 +1302,34 @@ if (args("pages")) {
|
|||||||
$pages = false;
|
$pages = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args("map")) {
|
if (!file_exists(args("map"))) {
|
||||||
msg("No brightness map specified",1);
|
|
||||||
} elseif (!file_exists(args("map"))) {
|
|
||||||
msg("Can't open brightness map",1);
|
msg("Can't open brightness map",1);
|
||||||
} elseif (substr(args("map"), -3, 3) == "JPG") {
|
|
||||||
//$method = "auto-level";
|
|
||||||
$method = "normalize";
|
|
||||||
$map = "scratch/".basename(args("map"),".JPG")."-divide_map.tif";
|
|
||||||
if (!file_exists($map)) {
|
|
||||||
@exec("convert -".$method." -colorspace gray ".args("map")." ".$map);
|
|
||||||
}
|
|
||||||
} elseif (substr(args("map"), -3, 3) == "jpg" | substr(args("map"), -3, 3) == "tif") {
|
|
||||||
$map = args("map");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args("mpush")) {
|
$ext = pathinfo(args("map"), PATHINFO_EXTENSION);
|
||||||
$map = basename(args("map"),".JPG")."-pushed.tif";
|
if (strtolower($ext) == "tif" && !args("mpush")) {
|
||||||
@exec("convert -level ".levels_ps_to_imgk(args("mpush"))." ".args("map")." ".$map);
|
$map = "scratch/".args("map");
|
||||||
|
copy(args("map"),$map);
|
||||||
|
} else {
|
||||||
|
$map = "scratch/".basename(args("map"),".".$ext)."-divide_map.tif";
|
||||||
|
$cmd = "convert -colorspace gray ";
|
||||||
|
if (args("mpush") == "auto") {
|
||||||
|
$cmd .= "-normalize ";
|
||||||
|
} elseif (args("mpush")) {
|
||||||
|
$cmd .= "-level ".levels_ps_to_imgk(args("mpush"))." ";
|
||||||
|
}
|
||||||
|
$cmd .= args("map")." ".$map;
|
||||||
|
msg("Converting map...");
|
||||||
|
@exec($cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pages) {
|
||||||
|
$ext = pathinfo($map, PATHINFO_EXTENSION);
|
||||||
|
$mapleft = str_replace(".".$ext, "-left.tif", $map);
|
||||||
|
$mapright = str_replace(".".$ext, "-right.tif", $map);
|
||||||
|
msg("Making map pages...");
|
||||||
|
@exec("convert -rotate 90 -flip ".$map." ".$mapleft." 2>&1");
|
||||||
|
@exec("convert -rotate 270 ".$map." ".$mapright." 2>&1");
|
||||||
}
|
}
|
||||||
|
|
||||||
$dest = rtrim(args("dir"), '/')."_divided";
|
$dest = rtrim(args("dir"), '/')."_divided";
|
||||||
@@ -1339,15 +1348,6 @@ if (args("q")) {
|
|||||||
$quality = 95;
|
$quality = 95;
|
||||||
}
|
}
|
||||||
|
|
||||||
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." 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: ";
|
echo "Building threads: ";
|
||||||
|
|
||||||
$thread = array();
|
$thread = array();
|
||||||
|
|||||||
Reference in New Issue
Block a user