#!/usr/bin/env php (int) $matches[1], "height" => (int) $matches[2], ]; } return null; } // Function to calculate normalized aspect ratio (1/x format) 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) { return $b ? $gcd($b, $a % $b) : $a; }; $divisor = $gcd($width, $height); $simplified = $width / $divisor . ":" . $height / $divisor; return [ "ratio" => $ratio, "normalized" => $normalized, "display" => $display, "simplified" => $simplified, ]; } // Function to calculate aspect ratio similarity (0-1, where 1 is perfect match) function calculateAspectRatioSimilarity($targetRatio, $existingRatio) { // Calculate the absolute difference between ratios $difference = abs($targetRatio - $existingRatio); // Normalize the difference (smaller difference = higher similarity) // Using an exponential decay function for better scoring $similarity = exp(-$difference * 5); return $similarity; } // Collect all image sizes from all categories function collectAllImageSizes($image_folders) { $allSizes = []; foreach ($image_folders as $category => $sizes) { if ($category === "cms_images") { continue; // Skip cms_images as it's a merged array } foreach ($sizes as $sizeName => $config) { if ( isset($config["width"]) && isset($config["height"]) && $config["height"] !== null ) { $allSizes[] = [ "name" => $sizeName, "category" => $category, "width" => $config["width"], "height" => $config["height"], "crop" => $config["crop"] ?? false, "forced" => $config["forced"] ?? false, "path" => $config["path"] ?? "", ]; } } } 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): "; $input = trim(fgets(STDIN)); $dimensions = parseDimensions($input); if (!$dimensions) { echo "\nāŒ Invalid format! Please use format like: 565x369px or 1920x1080\n\n"; exit(1); } echo "\nšŸ“ Analyzing dimensions: {$dimensions["width"]}x{$dimensions["height"]}px\n"; $targetRatio = getNormalizedAspectRatio( $dimensions["width"], $dimensions["height"], ); echo " Aspect ratio: {$targetRatio["simplified"]} = {$targetRatio["display"]}\n\n"; // Collect all image sizes $allSizes = collectAllImageSizes($image_folders); // Calculate similarity for each size based on aspect ratio only $matches = []; $seenRatios = []; // Track unique aspect ratios foreach ($allSizes as $size) { $existingRatio = getNormalizedAspectRatio($size["width"], $size["height"]); $similarity = calculateAspectRatioSimilarity( $targetRatio["ratio"], $existingRatio["ratio"], ); $ratioKey = $existingRatio["display"]; // Store the match $match = array_merge($size, [ "aspect_ratio" => $existingRatio["simplified"], "aspect_ratio_display" => $existingRatio["display"], "aspect_ratio_value" => $existingRatio["ratio"], "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) usort($matches, function ($a, $b) { $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 grouped by aspect ratio echo "šŸ” Image Sizes Grouped by Aspect Ratio:\n"; echo "===========================================\n\n"; // 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; } // Sort groups by similarity uasort($groupedMatches, function ($a, $b) { return $b["ratio"]["similarity"] <=> $a["ratio"]["similarity"]; }); // Display top 5 aspect ratio groups $topGroups = array_slice($groupedMatches, 0, 5); $displayCount = 0; 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 " Found " . count($group["sizes"]) . " size(s):\n\n"; foreach ($group["sizes"] as $match) { echo " • \033[1m{$match["name"]}\033[0m ({$match["category"]})\n"; echo " Size: {$match["width"]}x{$match["height"]}px"; if ($match["crop"]) { echo " | āœ‚ļø Cropped"; if ($match["forced"]) { echo " (Forced)"; } } echo "\n"; echo " Path: {$match["path"]}\n\n"; $displayCount++; if ($displayCount >= 15) { break 2; // Stop after 15 total sizes } } echo "\n"; } // Check for exact aspect ratio matches $exactMatches = array_filter($matches, function ($m) use ($targetRatio) { return abs($m["aspect_ratio_value"] - $targetRatio["ratio"]) < 0.001; }); if (!empty($exactMatches)) { echo "\nāœ… EXACT ASPECT RATIO MATCHES FOUND!\n"; echo "===========================================\n"; echo "These sizes have the exact same aspect ratio:\n\n"; foreach ($exactMatches as $match) { echo " • {$match["name"]} ({$match["width"]}x{$match["height"]}px) - {$match["category"]}\n"; } echo "\n"; } // Recommendations echo "\nšŸ’” Recommendations:\n"; echo "===========================================\n"; if (!empty($exactMatches)) { echo "āœ… PERFECT MATCHES: " . count($exactMatches) . " size(s) with exact aspect ratio\n"; echo " Use any of the sizes listed above.\n"; } else { $bestMatch = $matches[0]; $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 "Would you like to:\n"; echo " 1) Use an existing size\n"; echo " 2) Create a new size\n"; echo " 3) Exit\n"; echo "\nYour choice (1-3): "; $choice = trim(fgets(STDIN)); switch ($choice) { case "1": echo "\nāœ… Great! Use the size name from the list above in your image configuration.\n"; break; case "2": echo "\nšŸ“ To create a new size, add it to: sites/default/settings/image_folders.php\n"; echo " Use this template:\n\n"; echo " 'your_size_name' => [\n"; echo " 'path' => 'uploads/images/your_path',\n"; echo " 'width' => {$dimensions["width"]},\n"; echo " 'height' => {$dimensions["height"]},\n"; echo " 'forced' => true,\n"; echo " 'crop' => true,\n"; echo " ],\n\n"; break; case "3": echo "\nšŸ‘‹ Goodbye!\n"; break; default: echo "\nāŒ Invalid choice.\n"; } echo "\n";