Skip to content

Commit 5c8947c

Browse files
committed
Refactor ImageProcessor to use GD extension instead of Imagick
- Replace Spatie\Image with native GD extension for image processing - Add fallback support for multiple image processing methods - Maintain aspect ratio when resizing images - Support multiple output formats (JPEG, PNG, GIF, WebP) - Fixes 'Class Imagick not found' error in Slider module file uploads
1 parent d5207fd commit 5c8947c

1 file changed

Lines changed: 119 additions & 2 deletions

File tree

app/Services/ImageProcessor.php

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,132 @@
22

33
namespace App\Services;
44

5-
use Spatie\Image\Image;
65
use App\Services\Interfaces\ImageProcessorInterface;
76

87
class ImageProcessor implements ImageProcessorInterface
98
{
109
public function processImage(string $sourcePath, string $destinationPath, array $config): bool
1110
{
1211
try {
13-
$image = Image::load($sourcePath);
12+
// Check if we have GD extension available, otherwise use Intervention Image
13+
if (extension_loaded('gd')) {
14+
return $this->processWithGD($sourcePath, $destinationPath, $config);
15+
} elseif (class_exists('\Spatie\Image\Image')) {
16+
return $this->processWithSpatie($sourcePath, $destinationPath, $config);
17+
} else {
18+
// Fallback - just copy the file without processing
19+
return copy($sourcePath, $destinationPath);
20+
}
21+
} catch (\Exception $e) {
22+
return false;
23+
}
24+
}
25+
26+
private function processWithGD(string $sourcePath, string $destinationPath, array $config): bool
27+
{
28+
// Get image info
29+
$imageInfo = getimagesize($sourcePath);
30+
if (!$imageInfo) {
31+
return false;
32+
}
33+
34+
$mimeType = $imageInfo['mime'];
35+
$width = $imageInfo[0];
36+
$height = $imageInfo[1];
37+
38+
// Create image resource based on type
39+
switch ($mimeType) {
40+
case 'image/jpeg':
41+
$sourceImage = imagecreatefromjpeg($sourcePath);
42+
break;
43+
case 'image/png':
44+
$sourceImage = imagecreatefrompng($sourcePath);
45+
break;
46+
case 'image/gif':
47+
$sourceImage = imagecreatefromgif($sourcePath);
48+
break;
49+
case 'image/webp':
50+
$sourceImage = imagecreatefromwebp($sourcePath);
51+
break;
52+
default:
53+
return false;
54+
}
55+
56+
if (!$sourceImage) {
57+
return false;
58+
}
59+
60+
// Calculate new dimensions
61+
$newWidth = $config['width'] ?? $width;
62+
$newHeight = $config['height'] ?? $height;
63+
64+
// If both width and height are specified, maintain aspect ratio
65+
if (!empty($config['width']) && !empty($config['height'])) {
66+
$aspectRatio = $width / $height;
67+
$newAspectRatio = $newWidth / $newHeight;
68+
69+
if ($aspectRatio > $newAspectRatio) {
70+
// Image is wider than target ratio, fit by width
71+
$newHeight = $newWidth / $aspectRatio;
72+
} else {
73+
// Image is taller than target ratio, fit by height
74+
$newWidth = $newHeight * $aspectRatio;
75+
}
76+
}
77+
78+
// Create new image
79+
$newImage = imagecreatetruecolor((int)$newWidth, (int)$newHeight);
80+
81+
// Preserve transparency for PNG
82+
if ($mimeType === 'image/png') {
83+
imagealphablending($newImage, false);
84+
imagesavealpha($newImage, true);
85+
$transparent = imagecolorallocatealpha($newImage, 255, 255, 255, 127);
86+
imagefill($newImage, 0, 0, $transparent);
87+
}
88+
89+
// Resize image
90+
imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, (int)$newWidth, (int)$newHeight, $width, $height);
91+
92+
// Determine output format and quality
93+
$outputFormat = strtolower($config['format'] ?? 'original');
94+
$quality = $config['quality'] ?? 85;
95+
96+
// Set destination path with new format if specified
97+
if ($outputFormat !== 'original' && $outputFormat !== 'jpg') {
98+
$destinationPath = preg_replace('/\.[^.]+$/', '.' . $outputFormat, $destinationPath);
99+
}
100+
101+
// Save image based on format
102+
$result = false;
103+
switch ($outputFormat) {
104+
case 'png':
105+
$result = imagepng($newImage, $destinationPath, 9); // Max compression for PNG
106+
break;
107+
case 'gif':
108+
$result = imagegif($newImage, $destinationPath);
109+
break;
110+
case 'webp':
111+
$result = imagewebp($newImage, $destinationPath, $quality);
112+
break;
113+
case 'jpg':
114+
case 'jpeg':
115+
default:
116+
$result = imagejpeg($newImage, $destinationPath, $quality);
117+
break;
118+
}
119+
120+
// Clean up memory
121+
imagedestroy($sourceImage);
122+
imagedestroy($newImage);
123+
124+
return $result;
125+
}
126+
127+
private function processWithSpatie(string $sourcePath, string $destinationPath, array $config): bool
128+
{
129+
try {
130+
$image = \Spatie\Image\Image::load($sourcePath);
14131

15132
// Ustaw rozmiar
16133
if (!empty($config['width']) && !empty($config['height'])) {

0 commit comments

Comments
 (0)