Skip to content

Instantly share code, notes, and snippets.

@lleaff
Last active July 30, 2016 01:16
Show Gist options
  • Save lleaff/e39963432502dc543523a101cf77e7a3 to your computer and use it in GitHub Desktop.
Save lleaff/e39963432502dc543523a101cf77e7a3 to your computer and use it in GitHub Desktop.
Create a grid of images from those in a given webpage
#!/usr/bin/env php
<?php
/* =Config
*------------------------------------------------------------*/
$FONT_PATH = "OpenSans-Regular.ttf";
/* pixels */
$CELL_WIDTH_IDEAL = 100;
$CELL_HEIGHT_IDEAL = 100;
$CELL_WIDTH_MAX = 150;
$CELL_HEIGHT_MAX = 150;
$CELL_WIDTH_MIN = 32;
$CELL_HEIGHT_MIN = 32;
$GUTTER = 0;
$LEGEND_HEIGHT = 30;
/* Force square cells */
$FORCE_SQUARE = FALSE;
$EXCLUDE_PATTERNS = array(
'/background/',
'/[^\/]+_bg_[^\/]+\.\w+/',
'/^bg_[^\/]*\.\w+/',
'/[^\/]*_bg\.\w+$/'
);
/* If not empty, keep only images matching patterns */
$MATCH_PATTERNS = array();
/* =Dynamic globals
*------------------------------------------------------------*/
$foundCount = 0;
$excludedCount = 0;
$failedCount = 0;
$errors = array();
/* =Utilities
*------------------------------------------------------------*/
function nearestMultiple($of, $from) {
return $of / round($of / $from);
}
function identity($val) { return $val; }
function array_some($callback, $array) {
foreach ($array as $el) {
if ($callback($el)) {
return TRUE;
}
}
return FALSE;
}
function array_map_with_keys($callback, $array) {
$mapped = array();
foreach ($array as $key => $val) {
$mapped[$key] = $callback($val, $key);
}
return $mapped;
}
function array_flatten_once($array) {
return array_reduce($array, array_merge, array());
}
function array_filter_reset($array, $callback) {
return array_values(array_filter($array, $callback));
}
function plural($count) {
return $count > 1 ? "s" : "";
}
function color_string($color, $str) {
$colorCodes = array(
"red" => "0;31",
"green" => "0;32",
"brown" => "0;33",
"blue" => "0;34"
);
return "\033[" . $colorCodes[$c] . "m" . $str . "\033[0m";
}
function fatal_error($msg) {
echo color_string("red", $msg . "\n");
exit(1);
}
function log_error($msg) {
global $errors;
$errors[] = $msg;
}
function printLoggedErrors() {
global $errors;
if (!empty($errors)) {
$errorc = count($errors);
echo $errorc." erreur".plural($errorc).": \n";
foreach ($errors as $error) {
echo color_string('red', $error)."\n";
}
return 1;
} else {
return 0;
}
}
function is_url($str) {
return preg_match("/^https?:\/\//", $str) !== 0;
}
function url_exists($url) {
$curl = curl_init($url);
return (bool) $curl;
}
function get_url_content($url) {
if (!url_exists($url)) { fatal_error("Echec de lecture de la ressource: $url"); }
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_URL => $url,
CURLOPT_FOLLOWLOCATION, TRUE
));
$result = curl_exec($curl);
curl_close($curl);
if (!$result) { fatal_error("Echec de lecture du contenu: $url"); }
return $result;
}
function get_file_content($path) {
if (!file_exists($path)) { fatal_error("Le fichier n'existe pas: $path"); }
$file = fopen($path, "r");
if (!$file) { fatal_error("Echec de lecture du fichier: $path"); }
$result = fread($file, filesize($path));
if (!$result) { fatal_error("Echec de lecture du fichier: $path"); }
fclose($file);
return $result;
}
function normalized_extension_from_path($path) {
if (!preg_match('/.+\.(\w+)$/', $path, $match)) { return FALSE; }
if ($ext == "jpeg") { $ext = "jpg"; }
return strtolower($match[1]);
}
function getPathInfo($path) {
if (preg_match('/([\w\.]+)(?:\?.*$|$)/', $path, $match)) { $base = $match[1]; }
$filename = preg_replace('/\.[\w]+$/', '', $base ?: $path);
return array(
'path' => $path,
'basename' => $base ?: $path,
'filename' => $filename ?: $base,
'extension' => normalized_extension_from_path($base ?: $path));
}
/* =Options
*------------------------------------------------------------*/
$USAGE = <<<EOD
Usage: ./imagepanel.php [OPTIONS] HTML .. [SORTIE]
HTML: Un ou plusieurs chemins ou URLs vers des pages au format HTML contenant
des images a extraire.
SORTIE: Nom de fichier de la/les panel(s) produits
Options:
-g
-p
-j
Creer des images au format GIF, PNG ou JPEG, respectivement.
-L nombre Nombre maximal d'images recuperees.
-l nombre Nombre maximal d'images contenues dans un panel.
-n Afficher sous les images le nom de celles-ci (sans l'extension).
-N Afficher sous les images le nom de celles-ci (avec l'extension).
-W Largeur des images generees (en pixels)
-H Hauteur des images generees (en pixels)
-S Forcer dimensions carrees des miniatures
-G nombre Marge entre les images (en pixels)
--exclude regexp
Exclure les images dont le chemin est idientifie par le RegExp donne.
-b Ne pas utiliser les RegExps excluant les images de fond par defaut.
-m, --match
Ne prendre en compte que les images dont le chemin est identifie par
le RegExp donne.
-s Trier les images par orde alphabetique.
-h, --help Afficher ce message.
Notes:
Les arguments prenants des RegExps acceptent des expressions a la norme PCRE, sans
les delimiteurs (les '/' n'ont donc pas besoin d'etres echappes).
EOD;
$OPTS = getopt('gjl:L:nNpsbm:W:H:G:Sh', array('exclude:', 'match:', 'help'));
$OPTIONSWITHARGUMENTS = array('l','L','G','--exclude','m','W','H','--match');
if (isset($OPTS['h']) || isset($OPTS['help'])) {
echo $USAGE;
exit();
}
$EXT = call_user_func(function($OPTS) {
if (isset($OPTS['g'])) {
$EXT = 'gif';
} else if (isset($OPTS['j'])) {
$EXT = 'jpg';
} else if (isset($OPTS['p'])) {
$EXT = 'png';
} else {
$EXT = 'png'; // default format
}
return $EXT;
}, $OPTS);
$DISPLAY_NAME = isset($OPTS['n']) || isset($OPTS['N']);
$DISPLAY_EXT = $DISPLAY_NAME && isset($OPTS['N']);
if (isset($OPTS['L'])) {
if (gettype($OPTS['L']) == "array") { $OPTS['l'] = end($OPTS['l']); }
$MAXIMAGES = intval($OPTS['l']);
if ($MAXIMAGES <= 0) {
fatal_error("L'option -L doit etre un entier superieur a 0");
}
} else {
$MAXIMAGES = false;
}
if (isset($OPTS['l'])) {
if (gettype($OPTS['l']) == "array") { $OPTS['l'] = end($OPTS['l']); }
$MAXPANELIMAGES = intval($OPTS['l']);
if ($MAXPANELIMAGES <= 0) {
fatal_error("L'option -l doit etre un entier superieur a 0");
}
} else {
$MAXPANELIMAGES = false;
}
if (isset($OPTS['G'])) {
if (gettype($OPTS['G']) == "array") { $OPTS['G'] = end($OPTS['G']); }
$GUTTER = intval($OPTS['G']);
if ($GUTTER < 0) {
fatal_error("L'option -g doit etre un entier superieur ou egal a 0");
}
}
if (isset($OPTS['W'])) {
if (gettype($OPTS['W']) == "array") { $OPTS['W'] = end($OPTS['W']); }
$WIDTH = intval($OPTS['W']);
if ($WIDTH <= 0) {
fatal_error("L'option -W doit etre un entier superieur a 0");
}
} else {
$WIDTH = false;
}
if (isset($OPTS['H'])) {
if (gettype($OPTS['H']) == "array") { $OPTS['H'] = end($OPTS['H']); }
$HEIGHT = intval($OPTS['H']);
if ($HEIGHT <= 0) {
fatal_error("L'option -H doit etre un entier superieur a 0");
}
} else {
$HEIGHT = false;
}
if (isset($OPTS['S'])) {
$FORCE_SQUARE = TRUE;
}
if (isset($OPTS['b'])) {
$EXCLUDE_PATTERNS = array();
}
if (isset($OPTS['exclude'])) {
if (gettype($OPTS['exclude']) != "array") { $OPTS['exclude'] = array($OPTS['exclude']); }
foreach ($OPTS['exclude'] as $excludePattern) {
$EXCLUDE_PATTERNS[] = '/' . preg_replace('/\//', '\/', $excludePattern) . '/';
}
}
if (isset($OPTS['match'])) {
if (gettype($OPTS['match']) != "array") { $OPTS['match'] = array($OPTS['match']); }
foreach ($OPTS['match'] as $matchPattern) {
$MATCH_PATTERNS[] = '/' . preg_replace('/\//', '\/', $matchPattern) . '/';
}
}
if (isset($OPTS['m'])) {
if (gettype($OPTS['m']) != "array") { $OPTS['m'] = array($OPTS['m']); }
foreach ($OPTS['m'] as $matchPattern) {
$MATCH_PATTERNS[] = '/' . preg_replace('/\//', '\/', $matchPattern) . '/';
}
}
$SORT = isset($OPTS['s']);
/* =Parameters
*------------------------------------------------------------*/
$PARAMS = call_user_func(function($argv, $argc) {
global $OPTIONSWITHARGUMENTS;
$optionsregexp = "/(".implode('|', $OPTIONSWITHARGUMENTS).")/";
$PARAMS = array();
for ($i = 1; $i < $argc; $i++) {
if ($argv[$i][0] != '-') {
$PARAMS[] = $argv[$i];
} else {
if (preg_match($optionsregexp, $argv[$i])) {
$i++;
}
}
}
return $PARAMS;
}, $argv, $argc);
$OUTPUTBASE = array_pop($PARAMS);
$PATHS = $PARAMS;
if (!$OUTPUTBASE || !$PATHS) {
echo $USAGE;
exit();
}
/* =HTML fetching
*------------------------------------------------------------*/
function fetchHtmlPages($PATHS) {
$pages = array();
foreach ($PATHS as $path) {
if (is_url($path)) {
$content = get_url_content($path);
} else {
$content .= get_file_content($path);
}
$pages[] = array( 'path' => $path, 'content' => $content);
}
return $pages;
}
/* =App functions
*------------------------------------------------------------*/
function quit($matchedCount) {
global $foundCount;
global $excludedCount;
echo color_string("green", "$matchedCount images trouvees");
if ($excludedCount) { echo ", $excludedCount images exclues"; }
echo ".\n";
exit();
}
function printSummary($panelCount) {
global $foundCount;
global $failedCount;
global $excludedCount;
echo "$foundCount image".plural($foundCount)." trouvee".plural($foundCount).
($failedCount ?
", $failedCount transfert".plural($failedCount)." echouee".plural($failedCount) : "").
($excludedCount ?
", $excludedCount image".plural($excludedCount)." exclue".plural($excludedCount) : "").
", $panelCount panel".$pluralPanel." cree".$pluralPanel.
".\n";
};
/* =Image paths
*------------------------------------------------------------*/
$GDFORMATS = call_user_func(function() {
$gdinfo = gd_info();
return array(
'png' => isset($gdinfo['PNG Support']) && $gdinfo['PNG Support'],
'jpg' => isset($gdinfo['JPEG Support']) && $gdinfo['JPEG Support'],
'gif' => isset($gdinfo['GIF Read Support']) &&
$gdinfo['GIF Read Support'] && $gdinfo['GIF Create Support']
);
});
function get_protocol_from_path($path) {
$matches;
if (!preg_match('/^([a-z]+):\/\/.+/', $path, $matches)) {
log_error("Can't get protocol from path: $path");
return;
}
return $matches[1];
}
function domain_from_url($url) {
$pattern = "/(?:[a-z]+:\/\/)?[^\/]+/";
$matches;
if (!preg_match($pattern, $url, $matches)) {
log_error("Impossible de recuperer le domaine a partir de :\"$url\"");
return;
}
return $matches[0];
}
function dirname_from_url($url) {
$pattern = "/.*\//";
if (substr_count($url, '/') < 3) {
$url = ensure_trailing_slash($url);
}
$matches;
if (!preg_match($pattern, $url, $matches)) {
log_error("Impossible de recuperer la base d'url a partir de :\"$url\"");
return;
}
return $matches[0];
}
function ensure_trailing_slash($str) {
return rtrim($str, '/') . '/';
}
function get_base_href($html) {
$matches = array();
$pattern = '/<base[^>]+href="([^"<>]*)"/';
if (!preg_match($pattern, $html, $matches)) { return FALSE; }
else { return ensure_trailing_slash($matches[1]); }
}
define('PATH_PROTOCOLRELATIVE', 1);
define('PATH_ROOT', 2);
define('PATH_ABSOLUTE', 3);
define('PATH_RELATIVE', 4);
function path_format($path) {
if (preg_match('/^\/\/.+/', $path)) {
return PATH_PROTOCOLRELATIVE;
} else if (preg_match('/^\/[^\/]+/', $path)) {
return PATH_ROOT;
} else if (preg_match('/^[a-z]+:\/\/.+/', $path)){
return PATH_ABSOLUTE;
} else {
return PATH_RELATIVE;
}
}
function resolvePathFrom($url, $base = FALSE) {
return function($path) use ($url, $base) {
global $failedCount;
$isurl = is_url($url);
switch(path_format($path)) {
case PATH_PROTOCOLRELATIVE:
if (!$isurl) { $failedCount++; return FALSE; }
$resolved = get_protocol_from_path($url) . ':' . $path;
break;
case PATH_ROOT:
if ($isurl) {
$resolved = domain_from_url($url) . $path;
} else {
$resolved = $path;
}
break;
case PATH_RELATIVE:
$resolved = ($base ?: ensure_trailing_slash(dirname_from_url($url))) . $path;
break;
case PATH_ABSOLUTE:
$resolved = $path;
break;
}
return $resolved;
};
}
function gdSupportsFormat($path) {
global $GDFORMATS;
$ext = normalized_extension_from_path($path);
return $GDFORMATS[$ext];
}
function filterImagePath($path) {
global $EXCLUDE_PATTERNS;
global $MATCH_PATTERNS;
global $excludedCount;
if ($path === FALSE) { return FALSE; }
if (!gdSupportsFormat($path)) { return FALSE; }
foreach ($EXCLUDE_PATTERNS as $pattern) {
if (preg_match($pattern, $path)) {
$excludedCount++;
return FALSE;
}
}
if (empty($MATCH_PATTERNS)) { return TRUE; }
foreach ($MATCH_PATTERNS as $pattern) {
if (preg_match($pattern, $path)) {
return TRUE;
}
}
$excludedCount++;
return FALSE;
}
function formatImagePaths($pages, $MAXIMAGES) {
global $foundCount;
global $failedCount;
global $excludedCount;
$pattern = '/<img(?: |[^>]* )src="([^"<>]+)"/i';
$imagePaths = array();
foreach ($pages as $page) {
$currImagePaths = array();
if (!preg_match_all($pattern, $page['content'], $currImagePaths)) {
continue;
}
$imagePaths = array_merge(
$imagePaths,
array_map(resolvePathFrom($page['path'], get_base_href($page['content'])),
$currImagePaths[1]));
}
$foundCount = count($imagePaths);
$imagePaths = array_filter_reset($imagePaths, filterImagePath);
$images = array_map(getPathInfo, $imagePaths);
if ($MAXIMAGES) { $images = array_slice($images, 0, $MAXIMAGES); }
return $images;
}
/* =Images fetching
*------------------------------------------------------------*/
function createGDImage($path) {
$ext = normalized_extension_from_path($path);
switch ($ext) {
case "jpg":
return imagecreatefromjpeg($path);
case "gif":
return imagecreatefromgif($path);
case "png":
return imagecreatefrompng($path);
default:
log_error("Type d'image non supporte: $path");
return FALSE;
}
}
function addImageData($images) {
//do {
// $folder = '.imagepanel-img-'.str_pad(rand(0, 1000), 3, '0', STR_PAD_LEFT).'~/';
//} while (file_exists($folder));
for ($i = 0; $i < count($images); $i++) {
$img = createGDImage($images[$i]['path']);
if ($img) {
$images[$i]['gd'] = $img;
} else {
$images[$i] = FALSE;
}
}
$images = array_filter_reset($images, identity);
return $images;
}
function addImageDimensions($images) {
for ($i = 0; $i < count($images); $i++) {
$images[$i]['width'] = imagesx($images[$i]['gd']);
$images[$i]['height'] = imagesy($images[$i]['gd']);
}
return $images;
}
/* =Grid dimensions
*------------------------------------------------------------*/
function getAverage($getter) {
return function($array) use ($getter) {
$sum = 0;
foreach ($array as $item) {
$sum += $getter($item);
}
return $sum / count($array);
};
}
$getAverageWidth = getAverage(function($img) { return $img['width']; });
$getAverageHeight = getAverage(function($img) { return $img['height']; });
$getAverageAspectRatio = getAverage(function($img) { return $img['width'] / $img['height']; });
function guessAppropriateCellDimensions($images) {
global $CELL_WIDTH_IDEAL;
global $CELL_HEIGHT_IDEAL;
global $CELL_WIDTH_MAX;
global $CELL_HEIGHT_MAX;
global $FORCE_SQUARE;
global $WIDTH;
global $HEIGHT;
global $GUTTER;
global $LEGEND_HEIGHT;
global $DISPLAY_NAME;
global $DISPLAY_EXT;
global $getAverageWidth;
global $getAverageHeight;
global $getAverageAspectRatio;
$width = $CELL_WIDTH_IDEAL;
$height = $CELL_HEIGHT_IDEAL;
if (!$FORCE_SQUARE) {
// Adapt to aspect ratio
$averageAR = $getAverageAspectRatio($images);
if ($averageAR < 0.5) { /* images are in portrait orientation */
$height = $CELL_HEIGHT_MAX;
$width = $height * $averageAR;
} else if ($averageAR > 2) { /* images are in landscape orientation */
$width = $CELL_WIDTH_MAX;
$height = $width / $averageAR;
}
}
// Adapt to small dimensions
$averageWidth = $getAverageWidth($images);
$averageHeight = $getAverageHeight($images);
if ($averageWidth < $width) {
$width = $averageWidth;
}
if ($averageHeight < $height) {
$height = $averageHeight;
}
if ($FORCE_SQUARE) {
$width = min($height, $width);
$height = min($height, $width);
}
// Leave space for text
if ($DISPLAY_NAME) {
$width = max($width, 150);
$imgHeight = $height;
$height = $height + $LEGEND_HEIGHT;
}
// Adapt to forced canvas dimensions
if ($WIDTH) {
$width = nearestMultiple($WIDTH, $width) - $GUTTER;
}
if ($HEIGHT) {
$height = nearestMultiple($HEIGHT, $height) - $GUTTER;
}
$width = round($width);
$height = round($height);
return array(
'width' => $width,
'height' => $height,
'imgWidth' => $imgWidth ?: $width,
'imgHeight' => $imgHeight ?: $height,
);
}
function approximateColumnRowCount($cellDimensions, $cellCount) {
$cols = ceil(sqrt($cellCount));
$rows = ceil($cellCount / $cols);
$calcAR = function($cols, $rows) use ($cellDimensions) {
$width = $cellDimensions['width'] * $cols;
$height = $cellDimensions['height'] * $rows;
return $width / $height;
};
$delt = function($AR) {
return abs(1 - $AR);
};
$prevAR = $AR = $calcAR($cols, $rows);
while ($AR != 1 && $delt($AR) <= $delt($prevAR)) {
$prevAR = $AR;
if ($AR < 1) {
if ($rows <= 1) { break; }
$cols += 1;
$rows -= 1;
} else {
if ($cols <= 1) { break; }
$rows += 1;
$cols -= 1;
}
$AR = $calcAR($cols, $rows);
}
return array( 'cols' => $cols, 'rows' => $rows );
}
function calculatePanelDimensions($cellDimensions, $columnRowCount) {
global $GUTTER;
return array(
'width' => ($cellDimensions['width'] + $GUTTER) * $columnRowCount['cols'],
'height' => ($cellDimensions['height'] + $GUTTER) * $columnRowCount['rows'] );
}
/* =Grid building
*------------------------------------------------------------*/
function buildGridFrom($images, $columnRowCount) {
$grid = array();
for ($r = 0, $j = 0; $r < $columnRowCount['rows']; $r++) {
$row = array();
for ($c = 0; $c < $columnRowCount['cols'] && $j < count($images); $c++, $j++) {
$row[$c] = $images[$j];
}
$grid[$r] = $row;
}
return $grid;
}
function setGridCoordinates($grid, $cellDimensions) {
return array_map_with_keys(function($row, $rowN) use ($cellDimensions) {
return array_map_with_keys(function($cell, $colN) use ($rowN, $cellDimensions) {
global $GUTTER;
$cell['x'] = round($GUTTER / 2) + $colN * ($cellDimensions['width'] + $GUTTER);
$cell['y'] = round($GUTTER / 2) + $rowN * ($cellDimensions['height'] + $GUTTER);
return $cell;
}, $row);
}, $grid);
}
/* =Drawing
*------------------------------------------------------------*/
function calculateCroppedImage($img, $dimensions) {
$width = $img['width'];
$height = $img['height'];
$AR = $dimensions['width'] / $dimensions['height'];
$currAR = $img['width'] / $img['height'];
if ($AR > $currAR) {
$scale = ($height - $dimensions['height']);
$cropHeight = $height;
$cropWidth = $width / ($height/ $dimensions['height']) + $scale;
} else {
$scale = ($width - $dimensions['width']);
$cropWidth = $width;
$cropHeight = $height / ($width / $dimensions['width']) + $scale;
}
$offsetX = ($width - $cropWidth) / 2;
$offsetY = ($height - $cropHeight) / 2;
$img['cropWidth'] = $cropWidth;
$img['cropHeight'] = $cropHeight;
$img['cropX'] = $offsetX;
$img['cropY'] = $offsetY;
return $img;
}
function formatLegend($text, $height, $width, $fontsize) {
$text = str_split($text, round($width / $fontsize));
$newText = array_slice($text, 0, round($height / $fontsize));
if (count($newText) < count($text)) {
$newText[count($newText) - 1] .= "..." ;
}
$newText = implode("\n", $text);
return $newText;
}
function drawPanel($cells, $cellDimensions, $panelDimensions) {
global $LEGEND_HEIGHT;
global $DISPLAY_NAME;
global $DISPLAY_EXT;
global $FONT_PATH;
// Create transparent background image
$canvas = imagecreatetruecolor($panelDimensions['width'], $panelDimensions['height']);
imagealphablending($canvas, true);
$transparent = imagecolorallocatealpha($canvas, 255, 255, 255, 100);
$white = imagecolorallocate($canvas, 255, 255, 255);
$black = imagecolorallocate($canvas, 0, 0, 0);
imagefilledrectangle($canvas, 0, 0,
$panelDimensions['width'], $panelDimensions['height'],
$white);
imagealphablending($canvas, true);
$font = $FONT_PATH;
$fontsize = 9;
foreach ($cells as $cell) {
$cell = calculateCroppedImage($cell, $cellDimensions);
if (!imagecopyresampled(
$canvas, // dest
$cell['gd'], // src
$cell['x'], $cell['y'], // dest xy
$cell['cropX'], $cell['cropY'], // src xy
$cellDimensions['imgWidth'] + ($GUTTER / 2), // dest w
$cellDimensions['imgHeight'] + ($GUTTER / 2), // dest h
$cell['cropWidth'], $cell['cropHeight'] // src wh
)) { log_error('Echec de la copie de '.$cell['basename'].' sur le panel.'); }
if ($DISPLAY_NAME) {
$text = $DISPLAY_EXT ? $cell['basename'] : $cell['filename'];
imagettftext($canvas,
$fontsize, // font-size
0, // angle
$cell['x'] + 2, // x
$cell['y'] + $cellDimensions['imgHeight'] + 2 + $fontsize + ($GUTTER / 2), // y
$black, // color
$font, // font
formatLegend($text, $LEGEND_HEIGHT, $cellDimensions['width'], $fontsize) // text
);
}
}
imagesavealpha($canvas, true);
imagealphablending($canvas, true);
return $canvas;
}
/* =Output
*------------------------------------------------------------*/
function saveImage($img, $name) {
global $EXT;
switch ($EXT) {
case 'jpg':
$savefn = imagejpeg; break;
case 'gif':
$savefn = imagegif; break;
case 'png':
$savefn = imagepng; break;
}
return $savefn($img, "$name.$EXT");
}
function savePanels($panels) {
global $OUTPUTBASE;
global $EXT;
$name = $OUTPUTBASE;
$i = 1;
$multiple = count($panels) > 1;
while (file_exists($name.($multiple ? '' : ".$EXT"))) {
$name = $OUTPUTBASE."(".($i++).")" ;
}
if ($multiple) {
if (!mkdir($name)) { fatal_error("La creation du dossier \"$name\" a echouee"); }
}
foreach ($panels as $i => $panel) {
saveImage($panel, ($multiple ? $name.'/' : '').$name.($i ? $i : ''));
}
}
/* =Execution
*------------------------------------------------------------*/
function createPanelFromImages($images) {
$cellDimensions = guessAppropriateCellDimensions($images);
$columnRowCount = approximateColumnRowCount($cellDimensions, count($images));
$panelDimensions = calculatePanelDimensions($cellDimensions, $columnRowCount);
$grid = buildGridFrom($images, $columnRowCount);
$grid = setGridCoordinates($grid, $cellDimensions);
$cells = array_flatten_once($grid);
$panel = drawPanel($cells, $cellDimensions, $panelDimensions);
return $panel;
}
function processImages($images) {
global $MAXPANELIMAGES;
if ($MAXPANELIMAGES) {
$imagesSets = array_chunk($images, $MAXPANELIMAGES);
} else {
$imagesSets = array( $images );
}
return array_map(createPanelFromImages, $imagesSets);
}
function app() {
global $PATHS;
global $MAXIMAGES;
global $OUTPUTBASE;
$pages = fetchHtmlPages($PATHS);
$images = formatImagePaths($pages, $MAXIMAGES);
$images = addImageData($images);
$images = addImageDimensions($images);
if (empty($images)) { fatal_error('Aucune image trouve.'); }
$panels = processImages($images);
savePanels($panels);
$hasErrors = printLoggedErrors();
printSummary(count($panels));
return $hasErrors;
}
exit(app());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment