T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/soundstudiopro.com/private_html/utils/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/utils/image_compression.php
<?php
/**
 * Image Compression Utility
 * Automatically compresses and optimizes uploaded images
 */

/**
 * Compress and optimize an image file
 * 
 * @param string $filepath Path to the image file
 * @param array $options Compression options:
 *   - max_width: Maximum width (default: 1920)
 *   - max_height: Maximum height (default: 1920)
 *   - quality: JPEG quality 0-100 (default: 85)
 *   - convert_png_to_jpeg: Convert PNG to JPEG if no transparency (default: true)
 *   - max_file_size: Maximum file size in bytes (default: 500KB)
 * @return array Result with 'success', 'original_size', 'new_size', 'saved_bytes', 'filepath'
 */
function compressImage($filepath, $options = []) {
    // Default options
    $defaults = [
        'max_width' => 1920,
        'max_height' => 1920,
        'quality' => 85,
        'convert_png_to_jpeg' => true,
        'max_file_size' => 500 * 1024, // 500KB
    ];
    
    $options = array_merge($defaults, $options);
    
    // Check if GD is available
    if (!extension_loaded('gd')) {
        return [
            'success' => false,
            'error' => 'GD library not available'
        ];
    }
    
    // Check if file exists
    if (!file_exists($filepath)) {
        return [
            'success' => false,
            'error' => 'File not found'
        ];
    }
    
    $original_size = filesize($filepath);
    $image_info = @getimagesize($filepath);
    
    if (!$image_info) {
        return [
            'success' => false,
            'error' => 'Invalid image file'
        ];
    }
    
    $original_width = $image_info[0];
    $original_height = $image_info[1];
    $mime_type = $image_info['mime'];
    
    // If image is already small enough and file size is acceptable, skip compression
    if ($original_width <= $options['max_width'] && 
        $original_height <= $options['max_height'] && 
        $original_size <= $options['max_file_size']) {
        return [
            'success' => true,
            'original_size' => $original_size,
            'new_size' => $original_size,
            'saved_bytes' => 0,
            'filepath' => $filepath,
            'skipped' => true,
            'message' => 'Image already optimized'
        ];
    }
    
    // Load image based on type
    $source_image = null;
    switch ($mime_type) {
        case 'image/jpeg':
        case 'image/jpg':
            $source_image = @imagecreatefromjpeg($filepath);
            break;
        case 'image/png':
            $source_image = @imagecreatefrompng($filepath);
            break;
        case 'image/gif':
            $source_image = @imagecreatefromgif($filepath);
            break;
        case 'image/webp':
            if (function_exists('imagecreatefromwebp')) {
                $source_image = @imagecreatefromwebp($filepath);
            }
            break;
        default:
            return [
                'success' => false,
                'error' => 'Unsupported image type: ' . $mime_type
            ];
    }
    
    if (!$source_image) {
        return [
            'success' => false,
            'error' => 'Failed to load image'
        ];
    }
    
    // Calculate new dimensions maintaining aspect ratio
    $ratio = min($options['max_width'] / $original_width, $options['max_height'] / $original_height);
    $ratio = min($ratio, 1.0); // Don't upscale
    
    $new_width = (int)($original_width * $ratio);
    $new_height = (int)($original_height * $ratio);
    
    // Create new image
    $new_image = imagecreatetruecolor($new_width, $new_height);
    
    // Preserve transparency for PNG
    $has_transparency = false;
    if ($mime_type === 'image/png' || $mime_type === 'image/gif') {
        imagealphablending($new_image, false);
        imagesavealpha($new_image, true);
        $transparent = imagecolorallocatealpha($new_image, 0, 0, 0, 127);
        imagefill($new_image, 0, 0, $transparent);
        imagealphablending($new_image, true);
        
        // Check if PNG has transparency
        if ($mime_type === 'image/png') {
            $has_transparency = imagecolortransparent($source_image) >= 0 || 
                               (function_exists('imageistruecolor') && !imageistruecolor($source_image));
        }
    }
    
    // Resize image
    imagecopyresampled($new_image, $source_image, 0, 0, 0, 0, $new_width, $new_height, $original_width, $original_height);
    
    // Determine output format
    $output_format = 'jpeg';
    $output_path = $filepath;
    
    // Convert PNG to JPEG if no transparency and option is enabled
    if ($mime_type === 'image/png' && $options['convert_png_to_jpeg'] && !$has_transparency) {
        $output_path = preg_replace('/\.png$/i', '.jpg', $filepath);
        $output_format = 'jpeg';
    } elseif ($mime_type === 'image/png') {
        $output_format = 'png';
    } elseif ($mime_type === 'image/gif') {
        // Convert GIF to JPEG for better compression
        $output_path = preg_replace('/\.gif$/i', '.jpg', $filepath);
        $output_format = 'jpeg';
    }
    
    // Save compressed image
    $saved = false;
    switch ($output_format) {
        case 'jpeg':
            $saved = @imagejpeg($new_image, $output_path, $options['quality']);
            break;
        case 'png':
            // PNG compression level 6 (0-9, 6 is good balance)
            $saved = @imagepng($new_image, $output_path, 6);
            break;
    }
    
    // Clean up
    imagedestroy($source_image);
    imagedestroy($new_image);
    
    if (!$saved) {
        return [
            'success' => false,
            'error' => 'Failed to save compressed image'
        ];
    }
    
    // If file path changed (PNG->JPEG conversion), delete original
    if ($output_path !== $filepath && file_exists($filepath)) {
        @unlink($filepath);
    }
    
    $new_size = filesize($output_path);
    $saved_bytes = $original_size - $new_size;
    
    return [
        'success' => true,
        'original_size' => $original_size,
        'new_size' => $new_size,
        'saved_bytes' => $saved_bytes,
        'filepath' => $output_path,
        'original_dimensions' => [$original_width, $original_height],
        'new_dimensions' => [$new_width, $new_height],
        'format_changed' => ($output_path !== $filepath),
        'message' => sprintf('Compressed from %s to %s (saved %s)', 
            formatBytes($original_size), 
            formatBytes($new_size),
            formatBytes($saved_bytes))
    ];
}

/**
 * Format bytes to human readable format
 */
function formatBytes($bytes, $precision = 2) {
    $units = ['B', 'KB', 'MB', 'GB'];
    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);
    $bytes /= pow(1024, $pow);
    return round($bytes, $precision) . ' ' . $units[$pow];
}

/**
 * Compress profile image with profile-specific settings
 */
function compressProfileImage($filepath) {
    return compressImage($filepath, [
        'max_width' => 800,
        'max_height' => 800,
        'quality' => 85,
        'convert_png_to_jpeg' => true,
        'max_file_size' => 200 * 1024, // 200KB max for profile images
    ]);
}

/**
 * Compress track cover image with track cover-specific settings
 */
function compressTrackCover($filepath) {
    return compressImage($filepath, [
        'max_width' => 1920,
        'max_height' => 1920,
        'quality' => 85,
        'convert_png_to_jpeg' => true,
        'max_file_size' => 500 * 1024, // 500KB max for track covers
    ]);
}


CasperSecurity Mini