Remove old scripts, add a few helper scripts in Bash for compatibility

This commit is contained in:
Michiel Sikma
2020-02-17 00:04:54 +01:00
parent 738b66576d
commit 3ae1cdab46
9 changed files with 149 additions and 747 deletions

View File

@@ -1,91 +0,0 @@
#!/usr/bin/env php
<?php
# change_outline.php: modifies the outline color of a directory of sprites.
#
# Use with care, overwrites files.
$dir = @rtrim(trim($argv[1]), '/');
$GLOBALS['file_exts'] = array('png');
// To change:
$GLOBALS['hex_color'] = '31313100';
if (!isset($dir)) {
print('usage: change_outline.php dir'.PHP_EOL.'change_outline.php: error: too few arguments'.PHP_EOL);
exit();
}
$imgs = iterate_dir($dir);
$counter = 0;
$total = count($imgs);
print('dir: `'.$dir.'\' contains '.$total.' image files.'.PHP_EOL);
foreach ($imgs as $path => $img) {
$i = imagecreatefrompng($path);
// Turn on for debugging:
//$path_bits = explode('.', $path);
//$new_name = implode('.', array_slice($path_bits, 0, -1)).'2.png';
$new_name = $path;
imagealphablending($i, false);
imagesavealpha($i, true);
$changed = change_color($i);
if ($changed) {
imagepng($i, $new_name, 9);
}
print('img: '.$path.' (changed: '.($changed === true ? 'T' : 'F').')'.PHP_EOL);
}
function change_color($i)
{
$changed = false;
for ($x = imagesx($i); $x--;) {
for ($y = imagesy($i); $y--;) {
$rgb = imagecolorat($i, $x, $y);
$c = imagecolorsforindex($i, $rgb);
if (hex_color($c) === $GLOBALS['hex_color']) {
$new_c = imagecolorallocatealpha($i, 32, 32, 32, $c['alpha']);
imagesetpixel($i, $x, $y, $new_c);
$changed = true;
}
}
}
return $changed;
}
function hex_color($c) {
return sprintf("%02X%02X%02X%02X", $c['red'], $c['green'], $c['blue'], $c['alpha']);
}
function iterate_dir($dir)
{
$stack = array();
try {
$dir_it = new \DirectoryIterator($dir);
} catch (Exception $e) {
print('error: can\'t open directory: '.$dir);
continue;
}
foreach ($dir_it as $file) {
// Some checks to ensure it's a valid image.
if ($file->isDot()) {
continue;
}
if ($file->isDir()) {
$dir_stack = iterate_dir($dir.'/'.$file->getFilename());
$stack = array_merge($dir_stack, $stack);
continue;
}
$fn = $file->getFilename();
$fn_bits = explode('.', $fn);
$fn_ext = strtolower(trim(end($fn_bits)));
$file_path = $dir.'/'.$fn;
if (!in_array($fn_ext, $GLOBALS['file_exts'])) {
continue;
}
$stack[$file_path] = true;
}
return $stack;
}

55
scripts/crush.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env bash
PROJECT="pokesprite/crush"
DESCRIPTION="Minimizes PNG files by running pngcrush."
SELF="crush.sh"
VERSION="1.0.0"
function check_prerequisites {
arr=('pngcrush')
for tool in "${arr[@]}"; do
if ! command -v $tool >/dev/null 2>&1; then
echo "$SELF: error: the '$tool' command is not available"
exit
fi
done
}
function crush {
pngcrush -ow -fix -force -nofilecheck -brute -rem alla -oldtimestamp "$1"
}
function crush_all {
for f in "$@"; do
if [ ${f: -4} != ".png" ]; then
continue
fi
if [ ! -f "$f" ]; then
echo "$SELF: error: can't find file: $f"
continue
fi
crush "$f"
done
}
function argparse {
if [[ ( -z "$1" ) || ( "$1" == "-h" ) ]]; then
echo "usage: $SELF [-v] [-h] [files...]"
if [ "$1" == "-h" ]; then
echo "$DESCRIPTION"
exit 0
fi
exit 1
fi
if [ "$1" == "-v" ]; then
echo "$PROJECT-$VERSION"
exit
fi
check_prerequisites
crush_all "$@"
}
if [[ "${BASH_SOURCE[0]}" = "${0}" ]]; then
argparse $@
fi

30
scripts/crush_staged.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env bash
PROJECT="pokesprite/crush_staged"
DESCRIPTION="Minimizes all PNG files currently staged for commit."
SELF="crush_staged.sh"
VERSION="1.0.0"
BASE="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null 2>&1 && pwd)"
function argparse {
if [ "$1" == "-h" ]; then
echo "usage: $SELF [-v] [-h]"
echo "$DESCRIPTION"
exit
fi
if [ "$1" == "-v" ]; then
echo "$PROJECT-$VERSION"
exit
fi
files=$(git diff --name-only --staged)
if [ -z "$files" ]; then
echo "$SELF: error: no files have been staged"
exit 1
fi
exec "$BASE"/crush.sh $files
}
if [[ "${BASH_SOURCE[0]}" = "${0}" ]]; then
argparse $@
fi

View File

@@ -1,135 +0,0 @@
#!/usr/bin/env php
<?php
# find_new_images.php: used to crawl through the images from a dump and the
# already existing images to find out which ones are new.
#
# This script takes two directories, `old' and `new' (in that order), and then
# compares every file from `old' to every file in `new'. It's therefore very
# slow. This is used whenever there's a new image dump from a Pokémon cartridge
# to see which icons are new and which ones are already present in the current
# version of Pokésprite.
#
# This script requires libpuzzle to be compiled and present.
# See <https://github.com/jedisct1/libpuzzle> for more information.
set_time_limit(0);
$verbose = false;
$show_hits = true;
$dir_old = @$argv[1];
$dir_new = @$argv[2];
$treshold = 0.066;
$GLOBALS['file_exts'] = array('jpg', 'png', 'jpeg', 'gif');
if (!isset($dir_old) || !isset($dir_new)) {
print('usage: find_new_images.php old_dir new_dir'.PHP_EOL.'find_new_images.php: error: too few arguments'.PHP_EOL);
exit();
}
if (!is_dir($dir_old) || !is_dir($dir_new)) {
print('usage: find_new_images.php old_dir new_dir'.PHP_EOL.'find_new_images.php: error: old_dir or new_dir aren\'t directories'.PHP_EOL);
exit();
}
$imgs_old = iterate_dir($dir_old);
$imgs_new = iterate_dir($dir_new);
$unique_new_imgs = array();
$counter = 0;
$total = count($imgs_old) * count($imgs_new);
print('old: `'.$dir_old.'\' contains '.count($imgs_old).' image files.'.PHP_EOL);
print('new: `'.$dir_new.'\' contains '.count($imgs_new).' image files.'.PHP_EOL);
print(PHP_EOL.'We will make '.(count($imgs_old) * count($imgs_new)).' comparisons.'.PHP_EOL);
if ($verbose) {
print(PHP_EOL);
}
$counter_new = 0;
foreach ($imgs_new as $img_new_path => $img_new_info) {
foreach ($imgs_old as $img_old_path => $img_old_info) {
$diff = get_img_diff($img_new_path, $img_old_path);
if ($verbose || $show_hits) {
$perc = ($counter / $total);
if ($perc >= 1) {
$perc = ' 100%';
}
if ($perc < 1) {
$perc = sprintf('%04.1f%%', $perc * 100);
}
}
if ($verbose) {
print('['.$perc.'] comparing: `'.$img_new_path.'\' to `'.$img_old_path.'\': diff: '.$diff.PHP_EOL);
}
$counter += 1;
if ($diff < $treshold) {
// Found duplicate. We're looking for images that do not have duplicates.
$counter_new += 1;
$counter = $counter_new * count($imgs_old);
continue(2);
}
}
if ($show_hits) {
print('['.$perc.'] found unique image: `'.$img_new_path.'\'.'.PHP_EOL);
}
$counter_new += 1;
$unique_new_imgs[$img_new_path] = $img_new_info;
}
if ($verbose || $show_hits) {
print('[ 100%] done.'.PHP_EOL);
}
if (empty($unique_new_imgs)) {
print(PHP_EOL.'No unique images found.');
}
else {
print(PHP_EOL.'Amount of unique images found in `new\' directory: '.count($unique_new_imgs).PHP_EOL.PHP_EOL);
foreach ($unique_new_imgs as $path => $img) {
print(' '.$path.PHP_EOL);
}
}
print(PHP_EOL);
function iterate_dir($dir)
{
$stack = array();
try {
$dir_it = new \DirectoryIterator($dir);
} catch (Exception $e) {
print('error: can\'t open directory: '.$dir);
continue;
}
foreach ($dir_it as $file) {
// Some checks to ensure it's a valid image.
if ($file->isDot()) {
continue;
}
if ($file->isDir()) {
$dir_stack = iterate_dir($dir.'/'.$file->getFilename());
$stack = array_merge($dir_stack, $stack);
continue;
}
$fn = $file->getFilename();
$fn_bits = explode('.', $fn);
$fn_ext = strtolower(trim(end($fn_bits)));
$file_path = $dir.'/'.$fn;
if (!in_array($fn_ext, $GLOBALS['file_exts'])) {
continue;
}
$stack[$file_path] = true;
}
return $stack;
}
function get_img_diff($new, $old)
{
$diff = trim(exec('puzzle-diff "'.$new.'" "'.$old.'" 2>&1', $output, $code));
if ($code !== 0) {
print(PHP_EOL.'find_new_images.php: error: couldn\'t run the `puzzle-diff\' script'.PHP_EOL);
die();
}
return floatval($diff);
}

View File

@@ -1,8 +1,13 @@
#!/usr/bin/env python3
# prints JSON-usable japanese
# example: $ ./jsonjp.py モクロー
# output: "\u30e2\u30af\u30ed\u30fc"
# Prints input with non-ASCII characters converted to Unicode escape sequences.
# Example:
# $ ./jsonjp.py モクロー
# "\u30e2\u30af\u30ed\u30fc"
import json
import sys
print(json.dumps(sys.argv[1]))
if len(sys.argv) <= 1:
print('usage: jsonjp.py TEXT')
sys.exit(1)
print(json.dumps(sys.argv[1]))

View File

@@ -1,293 +0,0 @@
#!/usr/bin/env php
<?php
// Suffixed items: these appear in the database with a suffix string.
// E.g. the database contains 'red-apricorn', for the icon 'red' in the 'apricorn' set.
$suffix = array(
'apricorn', 'gem', 'petal', 'shard', 'mulch', 'flute', 'incense', 'memory', 'plate', 'berry', 'ball', 'fossil', 'scarf'
);
// Prefixed items: as above, but suffixed. Only 'roto'.
// E.g. in the database, 'roto-hatch', but in our files, icon 'hatch' in the 'roto' set.
$prefix = array(
'roto'
);
// Ignored items: these items are expected to not have an icon.
// See <https://github.com/msikma/pokesprite/pull/40#issuecomment-398071404>.
$ignored_items = array(
// Technical machines.
'tm00', 'tm01', 'tm02', 'tm03', 'tm04', 'tm05', 'tm06', 'tm07', 'tm08',
'tm09', 'tm10', 'tm11', 'tm12', 'tm13', 'tm14', 'tm15', 'tm16', 'tm17',
'tm18', 'tm19', 'tm20', 'tm21', 'tm22', 'tm23', 'tm24', 'tm25', 'tm26',
'tm27', 'tm28', 'tm29', 'tm30', 'tm31', 'tm32', 'tm33', 'tm34', 'tm35',
'tm36', 'tm37', 'tm38', 'tm39', 'tm40', 'tm41', 'tm42', 'tm43', 'tm44',
'tm45', 'tm46', 'tm47', 'tm48', 'tm49', 'tm50', 'tm51', 'tm52', 'tm53',
'tm54', 'tm55', 'tm56', 'tm57', 'tm58', 'tm59', 'tm60', 'tm61', 'tm62',
'tm63', 'tm64', 'tm65', 'tm66', 'tm67', 'tm68', 'tm69', 'tm70', 'tm71',
'tm72', 'tm73', 'tm74', 'tm75', 'tm76', 'tm77', 'tm78', 'tm79', 'tm80',
'tm81', 'tm82', 'tm83', 'tm84', 'tm85', 'tm86', 'tm87', 'tm88', 'tm89',
'tm90', 'tm91', 'tm92', 'tm93', 'tm94', 'tm95', 'tm96', 'tm97', 'tm98',
'tm99', 'tm100',
// Data cards.
'data-card-00', 'data-card-01', 'data-card-02', 'data-card-03',
'data-card-04', 'data-card-05', 'data-card-06', 'data-card-07',
'data-card-08', 'data-card-09', 'data-card-10', 'data-card-11',
'data-card-12', 'data-card-13', 'data-card-14', 'data-card-15',
'data-card-16', 'data-card-17', 'data-card-18', 'data-card-19',
'data-card-20', 'data-card-21', 'data-card-22', 'data-card-23',
'data-card-24', 'data-card-25', 'data-card-26', 'data-card-27',
'data-card-28', 'data-card-29', 'data-card-30',
// Hidden machines.
'hm00', 'hm01', 'hm02', 'hm03', 'hm04', 'hm05', 'hm06', 'hm07', 'hm08',
'hm09', 'hm10',
// Mega- items are in the database but don't have an icon representation.
'mega-pendant', 'mega-glasses', 'mega-glove', 'mega-anchor', 'mega-stickpin',
'mega-tiara', 'mega-anklet',
);
// Typoed items: these items have a typo in the database and need to be redirected
// to the correct file or we'll be unable to find the icon.
// See <https://github.com/msikma/pokesprite/pull/40#issuecomment-398071404>.
$typoed_items = array(
// The Xtransceiver icons.
'xtranceiver--red' => 'xtransceiver--red',
'xtranceiver--yellow' => 'xtransceiver--yellow',
);
// Aliased items: this is for items that share an icon but have a different name.
// I'm not sure if any of these need to have a different icon. It could be that there are
// extra icons that we are missing. Worth trying to check this out sometime.
$aliased_items = array(
'dna-splicers--merge' => 'dna-splicers',
'dna-splicers--split' => 'dna-splicers',
'ss-ticket--hoenn' => 'ss-ticket',
'n-solarizer--merge' => 'n-solarizer',
'n-lunarizer--merge' => 'n-lunarizer',
'n-solarizer--split' => 'n-solarizer',
'n-lunarizer--split' => 'n-lunarizer',
'ilimas-normalium-z' => 'normalium-z--bag',
'left-poke-ball' => 'poke-ball',
);
// Some icons are present in multiple sets. This disambiguates them.
$set_disambiguation = array(
// 'evo-item' and 'hold-item' have some identical icons.
'hold-item' => array('evo-item', 'hold-item'),
// Prefer 'medicine' and 'battle-item' over 'wonder-launcher'.
'medicine' => array('wonder-launcher', 'medicine'),
'battle-item' => array('wonder-launcher', 'battle-item'),
);
// We will attempt to match every item from the item export to an icon on the disk.
// Every item that doesn't have a matching icon is reported.
// Every icon that doesn't get used is reported.
$sets = get_icon_sets();
$items = get_item_export();
// Finally, we will generate a new JSON file with the following structure:
// First, a list of icon sets, which we will use when generating the icon spritesheet.
// Secondly, a key-value store of item ID to icon file.
$item_icon_database = array();
$icon_database = array();
$icon_usage = array();
// Run through every item in the database, match it with an icon (if it's not in the ignored item list)
// and save the resulting item/icon object to the final data set.
foreach ($items as $item) {
$obj = find_item_icon($item, $sets);
// Save the icon this item will use in the usage array.
$icon_path = $obj['icon']['set'].'/'.$obj['icon']['filename'];
$icon_usage[$icon_path] = true;
// Save the object to the item/icon database.
// If this item does not have an associated icon, the value will be null instead of a string.
// If it does have an icon, the string is a reference to an icon ID in 'icons'.
if ($obj['item']['id']) {
$item_icon_database[$obj['item']['id']] = !empty($obj['icon']['set']) ? array($obj['icon']['set'], $obj['icon']['filename']) : null;
}
if ($obj['icon']['set']) {
if (!isset($icon_database[$obj['icon']['set']])) {
$icon_database[$obj['icon']['set']] = array();
}
$icon_database[$obj['icon']['set']][$obj['icon']['filename']] = $obj;
}
}
// Now we need to run through all existing physical icons to see which ones were not linked to an item.
// We will also add these icons to the item/icon database, but without item data.
foreach ($sets as $set_name => $set_icons) {
foreach ($set_icons as $slug => $icon) {
$icon_path = $set_name.'/'.$icon['filename'];
if (isset($icon_usage[$icon_path])) {
continue;
}
// This icon has not been matched with an item.
$obj = make_item_icon(false, $slug, $set_name, $set_icons[$slug]);
$icon_usage[$icon_path] = true;
// Save the object to the item/icon database.
if (!isset($icon_database[$set_name])) {
$icon_database[$set_name] = array();
}
$icon_database[$set_name][$obj['icon']['filename']] = $obj;
}
}
// Now output the final file.
file_put_contents('icons.json', json_encode(array('items' => $item_icon_database, 'icons' => $icon_database), JSON_PRETTY_PRINT));
die("Output: './icons.json'. Done.\n");
/**
* Returns a matching icon file for a specific item.
* This is highly inefficient and any programmer would hate this code,
* but it doesn't really matter.
*/
function find_item_icon($item, $sets) {
global $ignored_items, $typoed_items, $aliased_items, $set_disambiguation;
// Match on the English language slug.
$slug = $item['slug']['eng'];
// Check if we are ignoring this item.
if (in_array($slug, $ignored_items)) {
return make_item_icon($item, $slug);
}
// Check if the item we're looking for is typoed.
$is_typoed = false;
if (isset($typoed_items[$slug])) {
$slug = $typoed_items[$slug];
$is_typoed = true;
}
// Check if the item is aliased to a different icon file.
$is_aliased = false;
if (isset($aliased_items[$slug])) {
$slug = $aliased_items[$slug];
$is_aliased = true;
}
$matches = array();
foreach ($sets as $set_name => $set_icons) {
$set_icon_slugs = array_keys($set_icons);
if (!in_array($slug, $set_icon_slugs)) {
continue;
}
// Found a match.
$matches[$set_name] = make_item_icon($item, $slug, $set_name, $set_icons[$slug], $is_typoed, $is_aliased);
}
if (count($matches) > 1) {
$keys = array_keys($matches);
$disamb = null;
print('Found '.count($matches).' matches for item #'.$item['id'].' ('.$item['slug']['eng'].'): ');
foreach ($set_disambiguation as $target => $items) {
if ($keys != $items) {
continue;
}
$disamb = $target;
}
if (!$disamb) {
print(implode(', ', $keys)." (no disambiguation)\n");
}
else {
print(implode(', ', $keys));
foreach ($matches as $set_name => $match_obj) {
if ($set_name === $disamb) {
print(" (".$disamb.")\n");
return $match_obj;
}
}
print(" (could not find disambiguation: ".$disamb.")\n");
}
}
return $matches[0];
// NOTE: we're quitting the script here on error because all items should be accounted for.
// If one isn't, we need to add it to ignored/aliased/typoed items.
print("Error: could not find item icon: \n");
var_dump($item);
die();
}
/**
* Returns a new format array with item and icon data.
*/
function make_item_icon($item = false, $slug = null, $set_name = null, $icon = false, $typoed = false, $aliased = false) {
$icon_data = array();
if ($item !== false) {
$icon_data['item'] = array(
'id' => $item['id'],
'slug' => $item['slug'],
'name' => $item['name'],
);
}
if ($typoed !== false) {
$icon_data['typoed'] = $typoed;
}
if ($aliased !== false) {
$icon_data['aliased'] = $aliased;
}
if ($icon !== false) {
$icon_data['icon'] = array(
'slug' => $slug,
'set' => $set_name,
'filename' => $icon['filename'],
);
}
return $icon_data;
}
/**
* Returns a list of all icon sets and icons inside: this is based on physical files.
*/
function get_icon_sets() {
global $suffix, $prefix;
$sets = array();
// Iterate through every directory inside 'icons'.
$root = new DirectoryIterator('./icons/');
foreach ($root as $set) {
$set_name = $set->getFilename();
if ($set->isDot() || $set_name === 'pokemon' || !$set->isDir()) continue;
if (!isset($sets[$set_name])) {
$sets[$set_name] = array();
}
// Now iterate over all files inside.
$dir = new DirectoryIterator('./icons/'.$set_name);
foreach ($dir as $icon) {
if ($icon->isDot()) continue;
$filename = $icon->getFilename();
$icon_name = pathinfo($icon->getFilename(), PATHINFO_FILENAME);
if (in_array($set_name, $suffix)) {
$icon_name = $icon_name.'-'.$set_name;
}
if (in_array($set_name, $prefix)) {
$icon_name = $set_name.'-'.$icon_name;
}
$sets[$set_name][$icon_name] = array(
'filename' => $filename
);
}
}
return $sets;
}
/**
* Returns the items from the database export.
*/
function get_item_export() {
$items = json_decode(file_get_contents('./data/item-export.json'), true);
return $items;
}

55
scripts/outline.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env bash
PROJECT="pokesprite/outline"
DESCRIPTION="Adds a Gen 8 style white outline to an icon (requires ImageMagick)."
SELF="outline.sh"
VERSION="1.0.0"
function check_prerequisites {
arr=('magick')
for tool in "${arr[@]}"; do
if ! command -v $tool >/dev/null 2>&1; then
echo "$SELF: error: the '$tool' command is not available"
exit
fi
done
}
function add_outline {
magick convert "$1" -background white -alpha background -channel a -morphology dilate square:1 +channel PNG32:"$1"
}
function add_outline_all {
for f in "$@"; do
if [ ${f: -4} != ".png" ]; then
continue
fi
if [ ! -f "$f" ]; then
echo "$SELF: error: can't find file: $f"
continue
fi
add_outline "$f"
done
}
function argparse {
if [[ ( -z "$1" ) || ( "$1" == "-h" ) ]]; then
echo "usage: $SELF [-v] [-h] [files...]"
if [ "$1" == "-h" ]; then
echo "$DESCRIPTION"
exit 0
fi
exit 1
fi
if [ "$1" == "-v" ]; then
echo "$PROJECT-$VERSION"
exit
fi
check_prerequisites
add_outline_all "$@"
}
if [[ "${BASH_SOURCE[0]}" = "${0}" ]]; then
argparse $@
fi

View File

@@ -1,79 +0,0 @@
#!/usr/bin/env php
<?php
# pngcrush_all.php: runs all images in a directory through pngcrush
# and saves the new file over the old file. Use with care.
#
# This script requires a pngcrush binary.
$verbose = false;
$dir = @rtrim(trim($argv[1]), '/');
$GLOBALS['file_exts'] = array('png');
$pngcrush_path = '../tools/pngcrush';
$pngcrush_cmd = $pngcrush_path.' -ow -fix -force -nofilecheck -brute -rem alla -oldtimestamp "%s"';
if (!isset($dir)) {
print('usage: pngcrush_all.php dir'.PHP_EOL.'pngcrush_all.php: error: too few arguments'.PHP_EOL);
exit();
}
if (!is_dir($dir)) {
print('usage: pngcrush_all.php dir'.PHP_EOL.'pngcrush_all.php: error: not a directory or not directory not accessible'.PHP_EOL);
exit();
}
if (!is_file($pngcrush_path)) {
print('usage: pngcrush_all.php dir'.PHP_EOL.'pngcrush_all.php: error: could not find pngcrush (tried: `'.$pngcrush_path.'\')'.PHP_EOL);
exit();
}
$imgs = iterate_dir($dir);
$counter = 0;
$total = count($imgs);
print('dir: `'.$dir.'\' contains '.$total.' image files.'.PHP_EOL);
foreach ($imgs as $path => $img) {
$old_size = filesize($path);
$cmd = sprintf($pngcrush_cmd.' 2>&1', $path);
exec($cmd, $output, $code);
if ($code !== 0) {
print(PHP_EOL.'pngcrush_all.php: error: there was a problem running `pngcrush\':'.PHP_EOL.PHP_EOL.' '.$cmd.PHP_EOL);
die();
}
clearstatcache();
$new_size = filesize($path);
print('Modified `'.$path.'\'. Old size: '.$old_size.'. New size: '.$new_size.'.'.PHP_EOL);
}
function iterate_dir($dir)
{
$stack = array();
try {
$dir_it = new \DirectoryIterator($dir);
} catch (Exception $e) {
print('error: can\'t open directory: '.$dir);
continue;
}
foreach ($dir_it as $file) {
// Some checks to ensure it's a valid image.
if ($file->isDot()) {
continue;
}
if ($file->isDir()) {
$dir_stack = iterate_dir($dir.'/'.$file->getFilename());
$stack = array_merge($dir_stack, $stack);
continue;
}
$fn = $file->getFilename();
$fn_bits = explode('.', $fn);
$fn_ext = strtolower(trim(end($fn_bits)));
$file_path = $dir.'/'.$fn;
if (!in_array($fn_ext, $GLOBALS['file_exts'])) {
continue;
}
$stack[$file_path] = true;
}
return $stack;
}

View File

@@ -1,145 +0,0 @@
#!/usr/bin/env php
<?php
# rename_to_most_similar.php: used to rename the images from a new dump
# to the filenames (and paths) of an old dump.
#
# Use with care, overwrites files.
#
# This script requires libpuzzle to be compiled and present.
# See <https://github.com/jedisct1/libpuzzle> for more information.
set_time_limit(0);
$verbose = false;
$show_hits = true;
$dir_old = @$argv[1];
$dir_new = @$argv[2];
$treshold = 0.09;
$GLOBALS['file_exts'] = array('jpg', 'png', 'jpeg', 'gif');
if (!isset($dir_old) || !isset($dir_new)) {
print('usage: rename_to_most_similar.php old_dir new_dir'.PHP_EOL.'rename_to_most_similar.php: error: too few arguments'.PHP_EOL);
exit();
}
if (!is_dir($dir_old) || !is_dir($dir_new)) {
print('usage: rename_to_most_similar.php old_dir new_dir'.PHP_EOL.'rename_to_most_similarrename_to_most_similar.php: error: old_dir or new_dir aren\'t directories'.PHP_EOL);
exit();
}
$imgs_old = iterate_dir($dir_old);
$imgs_new = iterate_dir($dir_new);
$renamed_imgs = 0;
overwrite_clean_imgs($imgs_old);
die('z');
$report = '<table border="2"><tr><th>New</th><th>Old</th></tr>';
$unique_new_imgs = array();
$counter = 0;
$total = count($imgs_old) * count($imgs_new);
print('old: `'.$dir_old.'\' contains '.count($imgs_old).' image files.'.PHP_EOL);
print('new: `'.$dir_new.'\' contains '.count($imgs_new).' image files.'.PHP_EOL);
print(PHP_EOL.'We will make '.(count($imgs_old) * count($imgs_new)).' comparisons.'.PHP_EOL);
if ($verbose) {
print(PHP_EOL);
}
$counter_new = 0;
foreach ($imgs_new as $img_new_path => $img_new_info) {
$best_match = array('diff' => 1, 'dir' => '', 'path' => '');
foreach ($imgs_old as $img_old_path => $img_old_info) {
$diff = get_img_diff($img_new_path, $img_old_path);
if ($verbose || $show_hits) {
$perc = ($counter / $total);
if ($perc >= 1) {
$perc = ' 100%';
}
if ($perc < 1) {
$perc = sprintf('%04.1f%%', $perc * 100);
}
}
if ($verbose) {
print('['.$perc.'] comparing: `'.$img_new_path.'\' to `'.$img_old_path.'\': diff: '.$diff.PHP_EOL);
}
$counter += 1;
if ($diff <= $treshold && $diff < $best_match['diff']) {
// Found a better match.
$best_match['diff'] = $diff;
$best_match['path'] = $img_old_path;
$best_match['dir'] = $img_old_info['dir'];
}
}
if ($best_match['diff'] <= $treshold && $show_hits) {
$report .= '<tr><td class="new">'.$img_new_tag.'</td><td class="old">'.$img_old_tag.'</td></tr>';
print('['.$perc.'] renaming `'..'\' to `'..'\' (trehold: '.$treshold.')');
rename_img($img_new_path, $best_match);
$renamed_imgs += 1;
}
$counter_new += 1;
}
if ($verbose || $show_hits) {
print('[ 100%] done.'.PHP_EOL);
}
print(PHP_EOL.'Amount of renamed images: '.$renamed_imgs);
print(PHP_EOL);
function rename_img($new_path, $old_info)
{
var_dump($new_path);
print_r($old_info);
}
function overwrite_clean_imgs($imgs)
{
foreach ($imgs as $img => $info) {
print_r($info);
}
}
function iterate_dir($dir)
{
$stack = array();
try {
$dir_it = new \DirectoryIterator($dir);
} catch (Exception $e) {
print('error: can\'t open directory: '.$dir);
continue;
}
foreach ($dir_it as $file) {
// Some checks to ensure it's a valid image.
if ($file->isDot()) {
continue;
}
if ($file->isDir()) {
$dir_stack = iterate_dir($dir.'/'.$file->getFilename());
$stack = array_merge($dir_stack, $stack);
continue;
}
$fn = $file->getFilename();
$fn_bits = explode('.', $fn);
$fn_ext = strtolower(trim(end($fn_bits)));
$file_path = $dir.'/'.$fn;
if (!in_array($fn_ext, $GLOBALS['file_exts'])) {
continue;
}
$stack[$file_path] = array('dir' => $dir.'/');
}
return $stack;
}
function get_img_diff($new, $old)
{
$diff = trim(exec('puzzle-diff "'.$new.'" "'.$old.'" 2>&1', $output, $code));
if ($code !== 0) {
print(PHP_EOL.'rename_to_most_similar.php: error: couldn\'t run the `puzzle-diff\' script'.PHP_EOL);
die();
}
return floatval($diff);
}