change find image size to only search by ratios

This commit is contained in:
2025-12-16 16:35:06 +02:00
parent 66adbd52a1
commit 31af274b5b

View File

@@ -1,39 +1,14 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php <?php
/** /**
* Image Size Finder * Image Aspect Ratio Finder
* *
* This script helps find the most suitable image size from image_folders.php * This script helps find image sizes from image_folders.php
* based on the proportions you provide. * with matching aspect ratios.
*/ */
// Main script - choose configuration file // Include the image folders configuration
echo "\n"; require_once __DIR__ . "/sites/default/settings/image_folders.php";
echo "===========================================\n";
echo " Image Size Finder Tool\n";
echo "===========================================\n\n";
echo "Choose which configuration to load:\n";
echo " 1) Whole site (sites/default/settings/image_folders.php)\n";
echo " 2) Shop/Categories (shop/includes/image_folders.php)\n";
echo "\nYour choice (1-2): ";
$configChoice = trim(fgets(STDIN));
switch ($configChoice) {
case "1":
require_once __DIR__ . "/sites/default/settings/image_folders.php";
echo "✅ Loaded: Whole site configuration\n\n";
break;
case "2":
require_once __DIR__ . "/shop/includes/image_folders.php";
echo "✅ Loaded: Shop/Categories configuration\n\n";
break;
default:
echo "\n❌ Invalid choice. Exiting.\n\n";
exit(1);
}
// Function to parse dimension input like "565x369px" // Function to parse dimension input like "565x369px"
function parseDimensions($input) function parseDimensions($input)
@@ -51,49 +26,48 @@ function parseDimensions($input)
return null; return null;
} }
// Function to calculate aspect ratio // Function to calculate normalized aspect ratio (1/x format)
function getAspectRatio($width, $height) function getNormalizedAspectRatio($width, $height)
{ {
// Calculate the ratio as 1/x where x = height/width
$ratio = $width / $height;
if ($ratio >= 1) {
// Landscape or square: represent as 1/x where x <= 1
$normalized = 1 / $ratio;
$display = "1/" . number_format($ratio, 3);
} else {
// Portrait: represent as 1/x where x > 1
$normalized = $ratio;
$display = "1/" . number_format(1 / $ratio, 3);
}
// Simplified ratio for display
$gcd = function ($a, $b) use (&$gcd) { $gcd = function ($a, $b) use (&$gcd) {
return $b ? $gcd($b, $a % $b) : $a; return $b ? $gcd($b, $a % $b) : $a;
}; };
$divisor = $gcd($width, $height); $divisor = $gcd($width, $height);
$simplified = $width / $divisor . ":" . $height / $divisor;
return [ return [
"ratio" => $width / $height, "ratio" => $ratio,
"simplified" => $width / $divisor . ":" . $height / $divisor, "normalized" => $normalized,
"display" => $display,
"simplified" => $simplified,
]; ];
} }
// Function to calculate similarity score // Function to calculate aspect ratio similarity (0-1, where 1 is perfect match)
function calculateSimilarity($target, $existing) function calculateAspectRatioSimilarity($targetRatio, $existingRatio)
{ {
// Calculate aspect ratio difference (0-1, where 0 is perfect match) // Calculate the absolute difference between ratios
$ratioScore = $difference = abs($targetRatio - $existingRatio);
abs($target["ratio"] - $existing["ratio"]) /
max($target["ratio"], $existing["ratio"]);
// Calculate size difference (0-1, where 0 is perfect match) // Normalize the difference (smaller difference = higher similarity)
$targetSize = $target["width"] * $target["height"]; // Using an exponential decay function for better scoring
$existingSize = $existing["width"] * $existing["height"]; $similarity = exp(-$difference * 5);
$sizeScore =
abs($targetSize - $existingSize) / max($targetSize, $existingSize);
// Calculate dimension differences return $similarity;
$widthScore =
abs($target["width"] - $existing["width"]) /
max($target["width"], $existing["width"]);
$heightScore =
abs($target["height"] - $existing["height"]) /
max($target["height"], $existing["height"]);
// Weighted score (aspect ratio is most important)
$totalScore =
$ratioScore * 0.5 +
$sizeScore * 0.2 +
$widthScore * 0.15 +
$heightScore * 0.15;
return 1 - $totalScore; // Convert to similarity (higher is better)
} }
// Collect all image sizes from all categories // Collect all image sizes from all categories
@@ -107,12 +81,16 @@ function collectAllImageSizes($image_folders)
} }
foreach ($sizes as $sizeName => $config) { foreach ($sizes as $sizeName => $config) {
if (isset($config["width"])) { if (
isset($config["width"]) &&
isset($config["height"]) &&
$config["height"] !== null
) {
$allSizes[] = [ $allSizes[] = [
"name" => $sizeName, "name" => $sizeName,
"category" => $category, "category" => $category,
"width" => $config["width"], "width" => $config["width"],
"height" => $config["height"] ?? null, "height" => $config["height"],
"crop" => $config["crop"] ?? false, "crop" => $config["crop"] ?? false,
"forced" => $config["forced"] ?? false, "forced" => $config["forced"] ?? false,
"path" => $config["path"] ?? "", "path" => $config["path"] ?? "",
@@ -124,6 +102,12 @@ function collectAllImageSizes($image_folders)
return $allSizes; return $allSizes;
} }
// Main script
echo "\n";
echo "===========================================\n";
echo " Image Aspect Ratio Finder Tool\n";
echo "===========================================\n\n";
echo "Enter image dimensions (e.g., 565x369px or 1920x1080): "; echo "Enter image dimensions (e.g., 565x369px or 1920x1080): ";
$input = trim(fgets(STDIN)); $input = trim(fgets(STDIN));
@@ -136,78 +120,127 @@ if (!$dimensions) {
echo "\n📐 Analyzing dimensions: {$dimensions["width"]}x{$dimensions["height"]}px\n"; echo "\n📐 Analyzing dimensions: {$dimensions["width"]}x{$dimensions["height"]}px\n";
$targetRatio = getAspectRatio($dimensions["width"], $dimensions["height"]); $targetRatio = getNormalizedAspectRatio(
echo " Aspect ratio: {$targetRatio["simplified"]} ({$targetRatio["ratio"]})\n\n"; $dimensions["width"],
$dimensions["height"],
);
echo " Aspect ratio: {$targetRatio["simplified"]} = {$targetRatio["display"]}\n\n";
// Collect all image sizes // Collect all image sizes
$allSizes = collectAllImageSizes($image_folders); $allSizes = collectAllImageSizes($image_folders);
// Calculate similarity for each size // Calculate similarity for each size based on aspect ratio only
$matches = []; $matches = [];
foreach ($allSizes as $size) { $seenRatios = []; // Track unique aspect ratios
if ($size["height"] === null) {
// Skip sizes without height (proportional scaling only)
continue;
}
$existingRatio = getAspectRatio($size["width"], $size["height"]); foreach ($allSizes as $size) {
$similarity = calculateSimilarity( $existingRatio = getNormalizedAspectRatio($size["width"], $size["height"]);
array_merge($dimensions, ["ratio" => $targetRatio["ratio"]]), $similarity = calculateAspectRatioSimilarity(
array_merge($size, ["ratio" => $existingRatio["ratio"]]), $targetRatio["ratio"],
$existingRatio["ratio"],
); );
$matches[] = array_merge($size, [ $ratioKey = $existingRatio["display"];
// Store the match
$match = array_merge($size, [
"aspect_ratio" => $existingRatio["simplified"], "aspect_ratio" => $existingRatio["simplified"],
"aspect_ratio_display" => $existingRatio["display"],
"aspect_ratio_value" => $existingRatio["ratio"], "aspect_ratio_value" => $existingRatio["ratio"],
"similarity" => $similarity, "similarity" => $similarity,
]); ]);
$matches[] = $match;
// Track unique aspect ratios for summary
if (!isset($seenRatios[$ratioKey])) {
$seenRatios[$ratioKey] = [
"ratio" => $existingRatio,
"count" => 0,
"sizes" => [],
];
}
$seenRatios[$ratioKey]["count"]++;
$seenRatios[$ratioKey]["sizes"][] = $match;
} }
// Sort by similarity (best matches first) // Sort by similarity (best matches first)
usort($matches, function ($a, $b) { usort($matches, function ($a, $b) {
return $b["similarity"] <=> $a["similarity"]; $simDiff = $b["similarity"] <=> $a["similarity"];
if ($simDiff !== 0) {
return $simDiff;
}
// If similarity is the same, sort by name
return $a["name"] <=> $b["name"];
}); });
// Display results // Display results grouped by aspect ratio
echo "🔍 Top 10 Most Similar Existing Sizes:\n"; echo "🔍 Image Sizes Grouped by Aspect Ratio:\n";
echo "===========================================\n\n"; echo "===========================================\n\n";
$topMatches = array_slice($matches, 0, 10); // Group matches by aspect ratio for display
$groupedMatches = [];
foreach ($matches as $match) {
$ratioKey = $match["aspect_ratio_display"];
if (!isset($groupedMatches[$ratioKey])) {
$groupedMatches[$ratioKey] = [
"ratio" => $match,
"sizes" => [],
];
}
$groupedMatches[$ratioKey]["sizes"][] = $match;
}
foreach ($topMatches as $index => $match) { // Sort groups by similarity
$matchPercent = round($match["similarity"] * 100, 1); uasort($groupedMatches, function ($a, $b) {
$matchBar = str_repeat("", (int) ($matchPercent / 5)); return $b["ratio"]["similarity"] <=> $a["ratio"]["similarity"];
});
echo $index + 1 . ". "; // Display top 5 aspect ratio groups
echo "\033[1m{$match["name"]}\033[0m"; $topGroups = array_slice($groupedMatches, 0, 5);
echo " (Category: {$match["category"]})\n"; $displayCount = 0;
echo " Size: {$match["width"]}x{$match["height"]}px\n";
echo " Aspect Ratio: {$match["aspect_ratio"]}\n"; foreach ($topGroups as $ratioKey => $group) {
$firstMatch = $group["ratio"];
$matchPercent = round($firstMatch["similarity"] * 100, 1);
$matchBar = str_repeat("", min(20, (int) ($matchPercent / 5)));
echo "📊 Aspect Ratio: {$firstMatch["aspect_ratio"]} = {$firstMatch["aspect_ratio_display"]}\n";
echo " Match: {$matchBar} {$matchPercent}%\n"; echo " Match: {$matchBar} {$matchPercent}%\n";
echo " Path: {$match["path"]}\n"; echo " Found " . count($group["sizes"]) . " size(s):\n\n";
if ($match["crop"]) { foreach ($group["sizes"] as $match) {
echo " ✂️ Cropped: Yes"; echo " \033[1m{$match["name"]}\033[0m ({$match["category"]})\n";
if ($match["forced"]) { echo " Size: {$match["width"]}x{$match["height"]}px";
echo " (Forced)"; if ($match["crop"]) {
echo " | ✂️ Cropped";
if ($match["forced"]) {
echo " (Forced)";
}
} }
echo "\n"; echo "\n";
echo " Path: {$match["path"]}\n\n";
$displayCount++;
if ($displayCount >= 15) {
break 2; // Stop after 15 total sizes
}
} }
echo "\n"; echo "\n";
} }
// Check for exact matches // Check for exact aspect ratio matches
$exactMatches = array_filter($matches, function ($m) use ($dimensions) { $exactMatches = array_filter($matches, function ($m) use ($targetRatio) {
return $m["width"] === $dimensions["width"] && return abs($m["aspect_ratio_value"] - $targetRatio["ratio"]) < 0.001;
$m["height"] === $dimensions["height"];
}); });
if (!empty($exactMatches)) { if (!empty($exactMatches)) {
echo "\n✅ EXACT MATCH FOUND!\n"; echo "\n✅ EXACT ASPECT RATIO MATCHES FOUND!\n";
echo "===========================================\n"; echo "===========================================\n";
echo "These sizes have the exact same aspect ratio:\n\n";
foreach ($exactMatches as $match) { foreach ($exactMatches as $match) {
echo "{$match["name"]} ({$match["category"]})\n"; echo "{$match["name"]} ({$match["width"]}x{$match["height"]}px) - {$match["category"]}\n";
} }
echo "\n"; echo "\n";
} }
@@ -216,18 +249,28 @@ if (!empty($exactMatches)) {
echo "\n💡 Recommendations:\n"; echo "\n💡 Recommendations:\n";
echo "===========================================\n"; echo "===========================================\n";
$bestMatch = $topMatches[0]; if (!empty($exactMatches)) {
$matchPercent = round($bestMatch["similarity"] * 100, 1); echo "✅ PERFECT MATCHES: " .
count($exactMatches) .
if ($matchPercent >= 95) { " size(s) with exact aspect ratio\n";
echo "✅ USE EXISTING: '{$bestMatch["name"]}' is very similar ({$matchPercent}% match)\n"; echo " Use any of the sizes listed above.\n";
echo " You can probably use this size instead.\n";
} elseif ($matchPercent >= 80) {
echo "⚠️ CONSIDER: '{$bestMatch["name"]}' is fairly similar ({$matchPercent}% match)\n";
echo " Evaluate if this size meets your needs or create a new one.\n";
} else { } else {
echo "🆕 CREATE NEW: No close matches found (best match: {$matchPercent}%)\n"; $bestMatch = $matches[0];
echo " Consider creating a new image size configuration.\n"; $matchPercent = round($bestMatch["similarity"] * 100, 1);
if ($matchPercent >= 95) {
echo "✅ VERY CLOSE: '{$bestMatch["name"]}' has nearly identical aspect ratio ({$matchPercent}% match)\n";
echo " Aspect ratio: {$bestMatch["aspect_ratio"]} = {$bestMatch["aspect_ratio_display"]}\n";
echo " You can probably use this size.\n";
} elseif ($matchPercent >= 80) {
echo "⚠️ SIMILAR: '{$bestMatch["name"]}' has a similar aspect ratio ({$matchPercent}% match)\n";
echo " Aspect ratio: {$bestMatch["aspect_ratio"]} = {$bestMatch["aspect_ratio_display"]}\n";
echo " Evaluate if this aspect ratio meets your needs.\n";
} else {
echo "🆕 CREATE NEW: No close aspect ratio matches found (best: {$matchPercent}%)\n";
echo " Your aspect ratio {$targetRatio["display"]} is unique.\n";
echo " Consider creating a new image size configuration.\n";
}
} }
echo "\n"; echo "\n";