#!/usr/bin/env php (int) $matches[1], 'height' => (int) $matches[2], ]; } return null; } // Function to calculate aspect ratio function getAspectRatio($width, $height) { $gcd = function ($a, $b) use (&$gcd) { return $b ? $gcd($b, $a % $b) : $a; }; $divisor = $gcd($width, $height); return [ 'ratio' => $width / $height, 'simplified' => $width / $divisor . ':' . $height / $divisor, ]; } // Function to calculate similarity score function calculateSimilarity($target, $existing) { // Calculate aspect ratio difference (0-1, where 0 is perfect match) $ratioScore = abs($target['ratio'] - $existing['ratio']) / max($target['ratio'], $existing['ratio']); // Calculate size difference (0-1, where 0 is perfect match) $targetSize = $target['width'] * $target['height']; $existingSize = $existing['width'] * $existing['height']; $sizeScore = abs($targetSize - $existingSize) / max($targetSize, $existingSize); // Calculate dimension differences $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 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'])) { $allSizes[] = [ 'name' => $sizeName, 'category' => $category, 'width' => $config['width'], 'height' => $config['height'] ?? null, 'crop' => $config['crop'] ?? false, 'forced' => $config['forced'] ?? false, 'path' => $config['path'] ?? '', ]; } } } return $allSizes; } // Main script echo "\n"; echo "===========================================\n"; echo " Image Size 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 = getAspectRatio($dimensions['width'], $dimensions['height']); echo " Aspect ratio: {$targetRatio['simplified']} ({$targetRatio['ratio']})\n\n"; // Collect all image sizes $allSizes = collectAllImageSizes($image_folders); // Calculate similarity for each size $matches = []; foreach ($allSizes as $size) { if ($size['height'] === null) { // Skip sizes without height (proportional scaling only) continue; } $existingRatio = getAspectRatio($size['width'], $size['height']); $similarity = calculateSimilarity( array_merge($dimensions, ['ratio' => $targetRatio['ratio']]), array_merge($size, ['ratio' => $existingRatio['ratio']]), ); $matches[] = array_merge($size, [ 'aspect_ratio' => $existingRatio['simplified'], 'aspect_ratio_value' => $existingRatio['ratio'], 'similarity' => $similarity, ]); } // Sort by similarity (best matches first) usort($matches, function ($a, $b) { return $b['similarity'] <=> $a['similarity']; }); // Display results echo "šŸ” Top 10 Most Similar Existing Sizes:\n"; echo "===========================================\n\n"; $topMatches = array_slice($matches, 0, 10); foreach ($topMatches as $index => $match) { $matchPercent = round($match['similarity'] * 100, 1); $matchBar = str_repeat('ā–ˆ', (int) ($matchPercent / 5)); echo $index + 1 . '. '; echo "\033[1m{$match['name']}\033[0m"; echo " (Category: {$match['category']})\n"; echo " Size: {$match['width']}x{$match['height']}px\n"; echo " Aspect Ratio: {$match['aspect_ratio']}\n"; echo " Match: {$matchBar} {$matchPercent}%\n"; echo " Path: {$match['path']}\n"; if ($match['crop']) { echo ' āœ‚ļø Cropped: Yes'; if ($match['forced']) { echo ' (Forced)'; } echo "\n"; } echo "\n"; } // Check for exact matches $exactMatches = array_filter($matches, function ($m) use ($dimensions) { return $m['width'] === $dimensions['width'] && $m['height'] === $dimensions['height']; }); if (!empty($exactMatches)) { echo "\nāœ… EXACT MATCH FOUND!\n"; echo "===========================================\n"; foreach ($exactMatches as $match) { echo " • {$match['name']} ({$match['category']})\n"; } echo "\n"; } // Recommendations echo "\nšŸ’” Recommendations:\n"; echo "===========================================\n"; $bestMatch = $topMatches[0]; $matchPercent = round($bestMatch['similarity'] * 100, 1); if ($matchPercent >= 95) { echo "āœ… USE EXISTING: '{$bestMatch['name']}' is very similar ({$matchPercent}% match)\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 { echo "šŸ†• CREATE NEW: No close matches found (best match: {$matchPercent}%)\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";