0 ) { $client_width = intval( $cookie_array[0] ); } // Second part of cookie is the client screen pixel density. if ( $hidpi ) { if ( count( $cookie_array ) > 1 ) { $pixel_density = $cookie_array[1]; } } } // Scale client screen width according to its pixel density. $client_width_scaled = $client_width * $pixel_density; // Find the closest upper resolution breakpoint for this client width. $resolution = $resolutions[0]; foreach ( $resolutions as $breakpoint ) { if ( $client_width_scaled <= $breakpoint ) { $resolution = $breakpoint; } } // Check if we are debugging. $debug = isset( $_GET['debug'] ) ? $_GET['debug'] : FALSE; // Setup script settings and save the in request scope. $_REQUEST['adaptive-images-settings'] = array( 'debug' => $debug, 'resolutions' => $resolutions, 'hidpi' => $hidpi, 'wp_content' => $wp_content_dir, 'cache_dir' => $cache_dir, 'jpg_quality' => $jpg_quality, 'png8' => $png8, 'sharpen' => $sharpen, 'watch_cache' => $watch_cache, 'browser_cache' => $browser_cache, 'request_uri' => $request_uri, 'source_file' => $source_file, 'client_width' => $client_width, 'pixel_density' => $pixel_density, 'resolution' => $resolution ); } return $_REQUEST['adaptive-images-settings']; } /** * Prints useful debugging information. * * @author Nevma (info@nevma.gr) * * @return void */ function adaptive_images_script_do_the_debug () { $settings = adaptive_images_script_get_settings(); if ( $settings['debug'] == 'true' ) { // Show debug info instead of resized image. $image_size = @GetImageSize( $settings['source_file'] ); header( 'HTTP/1.1 200 OK' ); header( 'Content-Type: text/html' ); ?> ADAPTIVE IMAGES DEBUG ADAPTIVE IMAGES DEBUG ===================== Script status ============== You are viewing this page instead of the image you requested. This is part of the debugging capabilities of the Adaptive Images plugin. Seeing this means the plugin is running alright and that the .htaccess configuration file is setup correctly!
Client width
Pixel density
Resolution
Cache exists
Cache is dir
Cache writable
User settings ==============
$resolutions
HiDPI
$cache_dir
$jpg_quality
$sharpen
$watch_cache
$browser_cache
Image requested ================
Image
Exists
Mime
Dimensions
Size
--- Remove "?debug=true" in the url to see your image. Add "?debug=original" to see the original, non-resized image. Add "?resolution=xxxx,y" to see the image resized in XXX pixels and y pixel density. 0 ) { // Add the cache control and expires headers header( 'Cache-Control: private, max-age=' . $browser_cache ); header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + $browser_cache ) . ' GMT' ); } // Add last modified cache header. header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', filemtime( $filename ) ) . ' GMT' ); // Send image file to user. header( 'Content-Length: ' . filesize( $filename ) ); header( 'X-Adaptive-Images: O~o~. ' . $case . ' .~o~O' ); readfile( $filename ); } /** * Checks if directory in the cache exists and is writeable and creates it if possible. Note that if the .htaccess * file has not been updated correctly then the request for an image will never reach this script and then this * code will not even be attempted to be called and the image will appear as "404 not found"/. Recall the starting * slash ("/") issue in the Rewrite of the .htaccess file. * * @author Nevma (info@nevma.gr) * * @return void */ function adaptive_images_script_ensure_cache_directory_ready ( $cache_path ) { if ( ! is_dir( $cache_path ) && ! is_writable( $cache_path ) && ! @mkdir( $cache_path, 0755, true ) && ! is_dir( $cache_path ) ) { return FALSE; } else { return TRUE; } } /** * Calculates the sharpness transformation factor. * * @author Nevma (info@nevma.gr) * * @param int $original_width The original width of the image to be sharpened. * @param int $final_width The final width of the image to be sharpened. * * @return float The calculated sharpness transformation factor. */ function adaptive_images_script_sharpness_factor ( $original_width, $final_width ) { // Normalize width. $final_width = $final_width * ( 750.0 / $original_width ); // Sharpness factors. $a = 52; $b = -0.27810650887573124; $c = 0.00047337278106508946; // Calculate sharpness factor. $result = $a + $b * $final_width + $c * $final_width * $final_width; return max( round( $result ), 0 ); } /** * Checks if the cached version of an image is stale and deletes it so it is regenerated later on. * * @author Nevma (info@nevma.gr) * * @param string $source_file The original image. * @param string $cache_file The cached version of the image. * @param string $resolution The resolution which has been selected to send to the user. * * @return void */ function adaptive_images_delete_stale_cache_image ( $source_file, $cache_file, $resolution ) { if ( file_exists( $cache_file ) ) { // Check image file timestamp. if ( filemtime( $cache_file ) >= filemtime( $source_file ) ) { return $cache_file; } unlink( $cache_file ); } } /** * Generates a resized version of an image and saves it in the image cache folder. * * @param string $source_file The original image to be resized. * @param string $cache_file The target file where the resized version will be cached. * @param int $resolution The resolution breakpoint at which the given image is to be resized. * @param int $jpg_quality The JPEG quality that will be used for resizing the images. * @param bool $png8 Whether to use PNG8 compression for PNGs or let 32bit PNGs. * @param bool $sharpen Whether to sharpen the resized images or not. * * @return array Associative array( bool: success, string: message) with the result of the image cache generation. */ function adaptive_images_script_generate_image ( $source_file, $cache_file, $resolution, $jpg_quality, $png8, $sharpen ) { // Get original image dimensions. $metadata = @GetImageSize( $source_file ); $width = $metadata[0]; $height = $metadata[1]; // Calculate resized image dimensions. $ratio = $height / $width; $new_width = $resolution; $new_height = ceil( $new_width * $ratio ); // Initialize image to resize. $extension = adaptive_images_script_get_file_extension( $source_file ); switch ( $extension ) { case 'png': // Case: PNG image. $source = @ImageCreateFromPng( $source_file ); break; case 'gif': // Case: GIF image. $source = @ImageCreateFromGif( $source_file ); break; default: // Case: JPEG image. $source = @ImageCreateFromJpeg( $source_file ); break; } // Start creating the resized image with a blank true color canvas. $destination = @ImageCreateTrueColor( $new_width, $new_height ); $anti_alias = TRUE; @ImageAntialias( $destination, $anti_alias ); // PNG images generation. if ( $extension == 'png' ) { // Create a transparent color and fill the blank canvas with it. $rbga_color = @ImageColorAllocateAlpha( $destination, 0, 0, 0, 127 ); @ImageColorTransparent( $destination, $rbga_color ); @ImageFill( $destination, 0, 0, $rbga_color ); // Disable blending of destination image to allow for alpha (transparency) above. $enable_alpha_blending = FALSE; @ImageAlphaBlending( $destination, $enable_alpha_blending ); // Save alpha (transparency) of destination image. $save_alpha = TRUE; @ImageSaveAlpha( $destination, $save_alpha ); // Copy source image to destination image with interpolation. @ImageCopyResampled( $destination, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height ); // Convert true colour image to pallette image to achieve PNG8 compression. if ( $png8 ) { $dither = TRUE; @ImageTrueColorToPalette( $destination, $dither, 255 ); } } // GIF images generation. if ( $extension == 'gif' ) { // Create a transparent color and fill the blank canvas with it. $rbga_color = @ImageColorAllocateAlpha( $destination, 0, 0, 0, 127 ); @ImageColorTransparent( $destination, $rbga_color ); @ImageFill( $destination, 0, 0, $rbga_color ); // Copy source image to destination image with interpolation. @ImageCopyResampled( $destination, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height ); // Convert true colour image to pallette image to achieve PNG8 compression. $dither = TRUE; @ImageTrueColorToPalette( $destination, $dither, 255 ); // Enable alpha blending of destination image. $enable_alpha_blending = TRUE; @ImageAlphaBlending( $destination, $enable_alpha_blending ); } // JPEG images generation. if ( $extension == 'jpg' || $extension == 'jpeg' ) { // Enable JPEG interlacing. @ImageInterlace( $destination, TRUE ); // Interpolates source image to destination image to make it clearer. @ImageCopyResampled( $destination, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height ); } // Cleanup source image from memory. @ImageDestroy( $source ); // Do sharpening if requested (only for JPEGs). if ( ( $extension == 'jpg' || $extension == 'jpeg' ) && $sharpen && function_exists( 'imageconvolution' ) ) { $sharpness_factor = adaptive_images_script_sharpness_factor( $width, $new_width ); $sharpness_transformation_matrix = array( array( -1, -2, -1 ), array( -2, $sharpness_factor + 12, -2 ), array( -1, -2, -1 ) ); // OR // $sharpenMatrix = array // ( // array(-1.2, -1, -1.2), // array(-1, 20, -1), // array(-1.2, -1, -1.2) // ); // $divisor = array_sum(array_map('array_sum', $sharpenMatrix)); // OR // $sharpen = array( // array(0.0, -1.0, 0.0), // array(-1.0, 5.0, -1.0), // array(0.0, -1.0, 0.0) // ); // $divisor = array_sum(array_map('array_sum', $sharpen)); // OR // $matrix = array( // array(-1, -1, -1), // array(-1, 16, -1), // array(-1, -1, -1), // ); // $divisor = array_sum(array_map('array_sum', $matrix)); @ImageConvolution( $destination, $sharpness_transformation_matrix, $sharpness_factor, 0 ); } // Check and ensure that cache directory to save the resized image is created and writeable. $cache_path = dirname( $cache_file ); if ( ! adaptive_images_script_ensure_cache_directory_ready( $cache_path ) ) { return array( 'success' => false, 'message' => 'Cache directory for image not accessible or not writeable.' ); } // Save resized image in cache. switch ( $extension ) { case 'png': // Lower PNG compression, bigger file, less time to produce. $png_compression_level = 6; $image_saved = @ImagePng( $destination, $cache_file, $png_compression_level, PNG_FILTER_NONE ); break; case 'gif': // The GIFs are alright! $image_saved = @ImageGif( $destination, $cache_file ); break; default: // Higher JPEG quality, higher image quality, bigger file. $image_saved = @ImageJpeg( $destination, $cache_file, $jpg_quality ); break; } // Cleanup destination image from memory. @ImageDestroy( $destination ); // Check if all OK. if ( ! $image_saved && ! file_exists( $cache_file ) ) { return array( 'success' => false, 'message' => 'Resized image could not be created.' ); } // Return file of resized and cached image. return array( 'success' => true, 'message' => $cache_file ); } /**********************************************************************************************************************/ /**************************************************************************** * * * * * SCRIPT LOGIC FOLLOWS * * ==================== * * * * * ****************************************************************************/ // Output nothing, to be used in cases of standalone unit tests in the future. if ( defined( CASE_SILENCE ) && CASE_SILENCE == TRUE ) { return; } // Collect plugin settings. $settings = adaptive_images_script_get_settings(); // Check if we are debugging instead of actually sending what was requested. if ( $settings['debug'] ) { // Special case with debugging output to the browser. adaptive_images_script_do_the_debug( $settings['debug'] ); exit(); } // Check if source image exists or not. if ( ! file_exists( $settings['source_file'] ) ) { // If the original image does not exist then there is nothig to send. adaptive_images_script_send_error_message( 'Image was not found or not available, sorry.' ); exit(); } // Special case where no cookie or url parameter is given. if ( ! isset( $_GET['resolution'] ) && ! isset( $_COOKIE['resolution'] ) ) { // Send the original image itself as the best solution. adaptive_images_script_send_image( $settings['source_file'], $settings['browser_cache'], CASE_OK_NO_COOKIE_OR_URL_PARAMETER ); exit(); } // Ensure main cache directory is created and writeable. if ( ! adaptive_images_script_ensure_cache_directory_ready( adaptive_images_script_get_main_cache_directory() ) ) { // Send the original image itself as the best solution. adaptive_images_script_send_image( $settings['source_file'], $settings['browser_cache'], CASE_ERROR_CACHE_DIRECTORY_NOT_READY ); exit(); } // Get original image dimensions. $image_size = @GetImageSize( $settings['source_file'] ); $image_width = $image_size[0]; // Special case where original image and device screen are both bigger than the biggest breakpoint. if ( $image_width > $settings['resolution'] && $settings['client_width'] > $settings['resolution'] ) { // Send the original image itself as the best solution. adaptive_images_script_send_image( $settings['source_file'], $settings['browser_cache'], CASE_OK_IMAGE_AND_DEVICE_BIGGER_THAN_BIGGEST_BREAKPOINT ); exit(); } // Special case where client width scaled by its pixel density is bigger than the selected (biggest) breakpoint. if ( $settings['client_width'] * $settings['pixel_density'] > $settings['resolution'] ) { // Send the original image itself as the best solution. adaptive_images_script_send_image( $settings['source_file'], $settings['browser_cache'], CASE_OK_CLIENT_WIDTH_DPI_BIGGER_THAN_BIGGEST_BREAKPOINT ); exit(); } // Special case where original image is smaller than the selected (smallest) breakpoint. if ( $image_width < $settings['resolution'] ) { // Send the original image itself as the best solution. adaptive_images_script_send_image( $settings['source_file'], $settings['browser_cache'], CASE_OK_SMALLER_THAN_SMALLEST_BREAKPOINT ); exit(); } // Locate cached image. $cache_file = adaptive_images_script_get_main_cache_directory() . '/' . $settings['resolution'] . $settings['request_uri']; // Check if cached image if stale and relete it if so. if ( file_exists( $cache_file ) ) { // Check if cached image is stale and delete it if so. if ( $settings['watch_cache'] ) { adaptive_images_delete_stale_cache_image( $settings['source_file'], $cache_file, $settings['resolution'] ); } } // Cached image is not yet created or has been deleted as stale. if ( ! file_exists( $cache_file ) ) { // So create cached image now. $result = adaptive_images_script_generate_image( $settings['source_file'], $cache_file, $settings['resolution'], $settings['jpg_quality'], $settings['png8'], $settings['sharpen'] ); // If cached image could not be created. if ( ! $result['success'] ) { // Send the original image itself as the best solution. adaptive_images_script_send_image( $source_file, $settings['browser_cache'], CASE_ERROR_RESIZED_IMAGE_NOT_CREATED ); exit(); } } // Send the cached image alright. adaptive_images_script_send_image( $cache_file, $settings['browser_cache'], CASE_OK_IMAGE_RESIZED ); exit(); ?>