Files
bookmarkly2/api/optimize_image.php
2025-10-01 00:07:16 +02:00

94 lines
3.2 KiB
PHP

<?php
// Start session if not already started
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Set proper content type
header('Content-Type: application/json');
// Basic authentication check
if (!isset($_SESSION['user_id'])) {
http_response_code(403);
echo json_encode(['success' => false, 'message' => 'Authentication required.']);
exit;
}
// Check if image path is provided
if (!isset($_POST['path']) || empty($_POST['path'])) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Image path not provided.']);
exit;
}
$imagePath = $_POST['path'];
// Sanitize the path: remove any query string to prevent issues with realpath()
$path_parts = parse_url($imagePath);
$imagePath = $path_parts['path'];
$baseDir = realpath(__DIR__ . '/../data/images/backgrounds');
$fullPath = realpath(__DIR__ . '/../' . $imagePath);
// Security check: ensure the file is within the backgrounds directory
if (!$fullPath || strpos($fullPath, $baseDir) !== 0 || !file_exists($fullPath)) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Invalid or non-existent image path.']);
exit;
}
// Check if ImageMagick is available
if (!extension_loaded('imagick')) {
http_response_code(500);
echo json_encode(['success' => false, 'message' => 'ImageMagick extension not available.']);
exit;
}
try {
$imagick = new Imagick($fullPath);
// Get image info
$width = $imagick->getImageWidth();
$height = $imagick->getImageHeight();
$format = $imagick->getImageFormat();
$maxWidth = 1920;
$quality = 85;
// Don't optimize if the image is already reasonably sized
if ($width <= $maxWidth) {
// Still, re-save with quality setting for JPEG
if (strtolower($format) === 'jpeg' || strtolower($format) === 'jpg') {
$imagick->setImageCompressionQuality($quality);
$imagick->writeImage($fullPath);
$imagick->destroy();
echo json_encode(['success' => true, 'message' => 'Image quality adjusted, but no resize needed.']);
exit;
}
// For other types, if no resize is needed, there's nothing to do.
$imagick->destroy();
echo json_encode(['success' => true, 'message' => 'Image is already optimized (width is within limit).']);
exit;
}
// Resize the image
$imagick->resizeImage($maxWidth, 0, Imagick::FILTER_LANCZOS, 1);
// Set quality for JPEG
if (strtolower($format) === 'jpeg' || strtolower($format) === 'jpg') {
$imagick->setImageCompressionQuality($quality);
}
// Write the optimized image
$imagick->writeImage($fullPath);
$imagick->destroy();
echo json_encode(['success' => true, 'message' => 'Image optimized successfully using ImageMagick.']);
} catch (ImagickException $e) {
http_response_code(500);
echo json_encode(['success' => false, 'message' => 'Error optimizing image: ' . $e->getMessage()]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
}