mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
165 lines
5.1 KiB
PHP
165 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\Utils;
|
|
|
|
class ImageAspectRatioDetector
|
|
{
|
|
/**
|
|
* Detect the aspect ratio of an image from its URL
|
|
*
|
|
* @param string $imageUrl The URL of the image to analyze
|
|
* @return float|null The aspect ratio (width/height) or null if detection fails
|
|
*/
|
|
public static function detectAspectRatio(string $imageUrl): ?float
|
|
{
|
|
if (empty($imageUrl)) {
|
|
return null;
|
|
}
|
|
|
|
// Handle local images (relative URLs)
|
|
if (!filter_var($imageUrl, FILTER_VALIDATE_URL)) {
|
|
$imageUrl = self::resolveLocalImagePath($imageUrl);
|
|
}
|
|
|
|
try {
|
|
// Get image dimensions
|
|
$imageInfo = @getimagesize($imageUrl);
|
|
|
|
if (!$imageInfo) {
|
|
return null;
|
|
}
|
|
|
|
$width = $imageInfo[0];
|
|
$height = $imageInfo[1];
|
|
|
|
if ($width <= 0 || $height <= 0) {
|
|
return null;
|
|
}
|
|
|
|
// Calculate aspect ratio (width/height)
|
|
$aspectRatio = round($width / $height, 3);
|
|
|
|
// Validate aspect ratio is reasonable (between 0.1 and 10)
|
|
if ($aspectRatio < 0.1 || $aspectRatio > 10) {
|
|
return null;
|
|
}
|
|
|
|
return $aspectRatio;
|
|
|
|
} catch (\Exception $e) {
|
|
// Log error but don't throw - aspect ratio detection should be non-blocking
|
|
error_log("Failed to detect aspect ratio for image {$imageUrl}: " . $e->getMessage());
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resolve local image path for getimagesize
|
|
*
|
|
* @param string $relativeUrl The relative URL of the image
|
|
* @return string The absolute file path
|
|
*/
|
|
private static function resolveLocalImagePath(string $relativeUrl): string
|
|
{
|
|
// Remove leading slash if present
|
|
$relativeUrl = ltrim($relativeUrl, '/');
|
|
|
|
// Define common image directories
|
|
$possiblePaths = [
|
|
__DIR__ . '/../../public/' . $relativeUrl,
|
|
__DIR__ . '/../../public/images/' . $relativeUrl,
|
|
__DIR__ . '/../../public/media/' . $relativeUrl,
|
|
__DIR__ . '/../../storage/' . $relativeUrl,
|
|
];
|
|
|
|
foreach ($possiblePaths as $path) {
|
|
if (file_exists($path)) {
|
|
return $path;
|
|
}
|
|
}
|
|
|
|
// If no local file found, return the original URL (might be external)
|
|
return $relativeUrl;
|
|
}
|
|
|
|
/**
|
|
* Get a CSS aspect ratio class based on the aspect ratio value
|
|
*
|
|
* @param float|null $aspectRatio The aspect ratio value
|
|
* @param string $defaultClass The default class to use if aspect ratio is null
|
|
* @return string The CSS class for the aspect ratio
|
|
*/
|
|
public static function getAspectRatioClass(?float $aspectRatio, string $defaultClass = 'aspect-[1/1]'): string
|
|
{
|
|
if ($aspectRatio === null) {
|
|
return $defaultClass;
|
|
}
|
|
|
|
// Common aspect ratios with nice round numbers
|
|
if (abs($aspectRatio - 1.333) < 0.05) { // 4:3
|
|
return 'aspect-[4/3]';
|
|
} elseif (abs($aspectRatio - 1.5) < 0.05) { // 3:2
|
|
return 'aspect-[3/2]';
|
|
} elseif (abs($aspectRatio - 1.667) < 0.05) { // 5:3
|
|
return 'aspect-[5/3]';
|
|
} elseif (abs($aspectRatio - 1.778) < 0.05) { // 16:9
|
|
return 'aspect-[16/9]';
|
|
} elseif (abs($aspectRatio - 0.667) < 0.05) { // 2:3
|
|
return 'aspect-[2/3]';
|
|
} elseif (abs($aspectRatio - 0.75) < 0.05) { // 3:4
|
|
return 'aspect-[3/4]';
|
|
} elseif (abs($aspectRatio - 1.0) < 0.05) { // 1:1
|
|
return 'aspect-[1/1]';
|
|
}
|
|
|
|
// For other ratios, use a custom aspect ratio class
|
|
// Tailwind doesn't support dynamic aspect ratios, so we'll use a data attribute approach
|
|
return 'aspect-custom';
|
|
}
|
|
|
|
/**
|
|
* Get inline styles for custom aspect ratios
|
|
*
|
|
* @param float|null $aspectRatio The aspect ratio value
|
|
* @return string CSS style string for custom aspect ratios
|
|
*/
|
|
public static function getCustomAspectRatioStyle(?float $aspectRatio): string
|
|
{
|
|
if ($aspectRatio === null) {
|
|
return '';
|
|
}
|
|
|
|
// Convert aspect ratio to padding-bottom percentage for aspect ratio simulation
|
|
$paddingBottom = (1 / $aspectRatio) * 100;
|
|
return "padding-bottom: {$paddingBottom}%;";
|
|
}
|
|
|
|
/**
|
|
* Batch detect aspect ratios for multiple images
|
|
*
|
|
* @param array $imageUrls Array of image URLs
|
|
* @return array Array of aspect ratios corresponding to the input URLs
|
|
*/
|
|
public static function batchDetectAspectRatios(array $imageUrls): array
|
|
{
|
|
$aspectRatios = [];
|
|
|
|
foreach ($imageUrls as $url) {
|
|
$aspectRatios[] = self::detectAspectRatio($url);
|
|
}
|
|
|
|
return $aspectRatios;
|
|
}
|
|
|
|
/**
|
|
* Validate if an aspect ratio value is reasonable
|
|
*
|
|
* @param float $aspectRatio The aspect ratio to validate
|
|
* @return bool True if the aspect ratio is valid
|
|
*/
|
|
public static function isValidAspectRatio(float $aspectRatio): bool
|
|
{
|
|
return $aspectRatio > 0.1 && $aspectRatio < 10;
|
|
}
|
|
}
|