/** * Resizes the image with the given id according to the configured max width and height settings * renders a json response indicating success/failure and dies */ function imsanity_resize_image() { imsanity_verify_permission(); global $wpdb; $id = intval($_POST['id']); if (!$id) { $results = array('success' => false, 'message' => __('Missing ID Parameter', 'imsanity')); echo json_encode($results); die; } // @TODO: probably doesn't need the join...? $query = $wpdb->prepare("select\n\t\t\t\t{$wpdb->posts}.ID as ID,\n\t\t\t\t{$wpdb->posts}.guid as guid,\n\t\t\t\t{$wpdb->postmeta}.meta_value as file_meta\n\t\t\t\tfrom {$wpdb->posts}\n\t\t\t\tinner join {$wpdb->postmeta} on {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id and {$wpdb->postmeta}.meta_key = %s\n\t\t\t\twhere {$wpdb->posts}.ID = %d\n\t\t\t\tand {$wpdb->posts}.post_type = %s\n\t\t\t\tand {$wpdb->posts}.post_mime_type like %s", array('_wp_attachment_metadata', $id, 'attachment', 'image%')); $images = $wpdb->get_results($query); if ($images) { $image = $images[0]; $meta = unserialize($image->file_meta); $uploads = wp_upload_dir(); $oldPath = $uploads['basedir'] . "/" . $meta['file']; $maxW = imsanity_get_option('imsanity_max_width', IMSANITY_DEFAULT_MAX_WIDTH); $maxH = imsanity_get_option('imsanity_max_height', IMSANITY_DEFAULT_MAX_HEIGHT); // method one - slow but accurate, get file size from file itself // list($oldW, $oldH) = getimagesize( $oldPath ); // method two - get file size from meta, fast but resize will fail if meta is out of sync $oldW = $meta['width']; $oldH = $meta['height']; if ($oldW > $maxW && $maxW > 0 || $oldH > $maxH && $maxH > 0) { $quality = imsanity_get_option('imsanity_quality', IMSANITY_DEFAULT_QUALITY); list($newW, $newH) = wp_constrain_dimensions($oldW, $oldH, $maxW, $maxH); $resizeResult = imsanity_image_resize($oldPath, $newW, $newH, false, null, null, $quality); // $resizeResult = new WP_Error('invalid_image', __('Could not read image size'), $oldPath); // uncommend to debug fail condition if (!is_wp_error($resizeResult)) { $newPath = $resizeResult; if ($newPath != $oldPath) { // remove original and replace with re-sized image unlink($oldPath); rename($newPath, $oldPath); } $meta['width'] = $newW; $meta['height'] = $newH; // @TODO replace custom query with update_post_meta $update_query = $wpdb->prepare("update {$wpdb->postmeta}\n\t\t\t\t\t\tset {$wpdb->postmeta}.meta_value = %s\n\t\t\t\t\t\twhere {$wpdb->postmeta}.post_id = %d\n\t\t\t\t\t\tand {$wpdb->postmeta}.meta_key = %s", array(maybe_serialize($meta), $image->ID, '_wp_attachment_metadata')); $wpdb->query($update_query); $results = array('success' => true, 'id' => $id, 'message' => sprintf(__('OK: %s', 'imsanity'), $oldPath)); } else { $results = array('success' => false, 'id' => $id, 'message' => sprintf(__('ERROR: %s (%s)', 'imsanity'), $oldPath, htmlentities($resizeResult->get_error_message()))); } } else { $results = array('success' => true, 'id' => $id, 'message' => sprintf(__('SKIPPED: %s (Resize not required)', 'imsanity'), $oldPath)); } } else { $results = array('success' => false, 'id' => $id, 'message' => sprintf(__('ERROR: (Attachment with ID of %s not found) ', 'imsanity'), htmlentities($id))); } // if there is a quota we need to reset the directory size cache so it will re-calculate delete_transient('dirsize_cache'); echo json_encode($results); die; // required by wordpress }
/** * Handler after a file has been uploaded. If the file is an image, check the size * to see if it is too big and, if so, resize and overwrite the original * @param Array $params */ function imsanity_handle_upload($params) { /* debug logging... */ // file_put_contents ( "debug.txt" , print_r($params,1) . "\n" ); $option_convert_bmp = imsanity_get_option('imsanity_bmp_to_jpg', IMSANITY_DEFAULT_BMP_TO_JPG); if ($params['type'] == 'image/bmp' && $option_convert_bmp) { $params = imsanity_bmp_to_jpg($params); } // make sure this is a type of image that we want to convert and that it exists // @TODO when uploads occur via RPC the image may not exist at this location $oldPath = $params['file']; if (!is_wp_error($params) && file_exists($oldPath) && in_array($params['type'], array('image/png', 'image/gif', 'image/jpeg'))) { // figure out where the upload is coming from $source = imsanity_get_source(); list($maxW, $maxH) = imsanity_get_max_width_height($source); list($oldW, $oldH) = getimagesize($oldPath); /* HACK: if getimagesize returns an incorrect value (sometimes due to bad EXIF data..?) $img = imagecreatefromjpeg ($oldPath); $oldW = imagesx ($img); $oldH = imagesy ($img); imagedestroy ($img); //*/ /* HACK: an animated gif may have different frame sizes. to get the "screen" size $data = ''; // TODO: convert file to binary $header = unpack('@6/vwidth/vheight', $data ); $oldW = $header['width']; $oldH = $header['width']; //*/ if ($oldW > $maxW && $maxW > 0 || $oldH > $maxH && $maxH > 0) { $quality = imsanity_get_option('imsanity_quality', IMSANITY_DEFAULT_QUALITY); list($newW, $newH) = wp_constrain_dimensions($oldW, $oldH, $maxW, $maxH); // this is wordpress prior to 3.5 (image_resize deprecated as of 3.5) $resizeResult = imsanity_image_resize($oldPath, $newW, $newH, false, null, null, $quality); /* uncomment to debug error handling code: */ // $resizeResult = new WP_Error('invalid_image', __(print_r($_REQUEST)), $oldPath); // regardless of success/fail we're going to remove the original upload unlink($oldPath); if (!is_wp_error($resizeResult)) { $newPath = $resizeResult; // remove original and replace with re-sized image rename($newPath, $oldPath); } else { // resize didn't work, likely because the image processing libraries are missing $params = wp_handle_upload_error($oldPath, sprintf(__("Oh Snap! Imsanity was unable to resize this image " . "for the following reason: '%s'\n\t\t\t\t\t. If you continue to see this error message, you may need to either install missing server" . " components or disable the Imsanity plugin." . " If you think you have discovered a bug, please report it on the Imsanity support forum.", 'imsanity'), $resizeResult->get_error_message())); } } } return $params; }
/** * Handler after a file has been uploaded. If the file is an image, check the size * to see if it is too big and, if so, resize and overwrite the original * @param Array $params */ function imsanity_handle_upload($params) { /* debug logging... */ // file_put_contents ( "debug.txt" , print_r($params,1) . "\n" ); // if "noresize" is included in the filename then we will bypass imsanity scaling if (strpos($params['file'], 'noresize') !== false) { return $params; } // if preferences specify so then we can convert an original bmp or png file into jpg if ($params['type'] == 'image/bmp' && imsanity_get_option('imsanity_bmp_to_jpg', IMSANITY_DEFAULT_BMP_TO_JPG)) { $params = imsanity_convert_to_jpg('bmp', $params); } if ($params['type'] == 'image/png' && imsanity_get_option('imsanity_png_to_jpg', IMSANITY_DEFAULT_PNG_TO_JPG)) { $params = imsanity_convert_to_jpg('png', $params); } // make sure this is a type of image that we want to convert and that it exists // @TODO when uploads occur via RPC the image may not exist at this location $oldPath = $params['file']; // @HACK not currently working // @see https://wordpress.org/support/topic/images-dont-resize-when-uploaded-via-mobile-device // if (!file_exists($oldPath)) { // $ud = wp_upload_dir(); // $oldPath = $ud['path'] . DIRECTORY_SEPARATOR . $oldPath; // } if (!is_wp_error($params) && file_exists($oldPath) && in_array($params['type'], array('image/png', 'image/gif', 'image/jpeg'))) { // figure out where the upload is coming from $source = imsanity_get_source(); $quality = imsanity_get_option('imsanity_quality', IMSANITY_DEFAULT_QUALITY); list($maxW, $maxH) = imsanity_get_max_width_height($source); list($oldW, $oldH) = getimagesize($oldPath); $oldFilesize = filesize($oldPath); // estimated image quality algorithm from http://stackoverflow.com/a/19255481 $oldQuality = 101 - $oldW * $oldH * 3 / $oldFilesize; /* HACK: if getimagesize returns an incorrect value (sometimes due to bad EXIF data..?) $img = imagecreatefromjpeg ($oldPath); $oldW = imagesx ($img); $oldH = imagesy ($img); imagedestroy ($img); //*/ /* HACK: an animated gif may have different frame sizes. to get the "screen" size $data = ''; // TODO: convert file to binary $header = unpack('@6/vwidth/vheight', $data ); $oldW = $header['width']; $oldH = $header['width']; //*/ if ($oldW > $maxW && $maxW > 0 || $oldH > $maxH && $maxH > 0 || $params['type'] == 'image/jpeg' && imsanity_get_option('imsanity_enforce_quality', IMSANITY_DEFAULT_ENFORCE_QUALITY) && $oldQuality > $quality) { list($newW, $newH) = wp_constrain_dimensions($oldW, $oldH, $maxW, $maxH); // this is wordpress prior to 3.5 (image_resize deprecated as of 3.5) $resizeResult = imsanity_image_resize($oldPath, $newW, $newH, false, null, null, $quality); /* uncomment to debug error handling code: */ // $resizeResult = new WP_Error('invalid_image', __(print_r($_REQUEST)), $oldPath); if (!is_wp_error($resizeResult)) { $newPath = $resizeResult; if (filesize($newPath) < filesize($oldPath)) { // we saved some file space. remove original and replace with resized image unlink($oldPath); rename($newPath, $oldPath); } else { // theresized image is actually bigger in filesize (most likely due to jpg quality). // keep the old one and just get rid of the resized image unlink($newPath); } } else { // resize didn't work, likely because the image processing libraries are missing // remove the old image so we don't leave orphan files hanging around unlink($oldPath); $params = wp_handle_upload_error($oldPath, sprintf(__("Oh Snap! Imsanity was unable to resize this image " . "for the following reason: '%s'\n\t\t\t\t\t. If you continue to see this error message, you may need to either install missing server" . " components or disable the Imsanity plugin." . " If you think you have discovered a bug, please report it on the Imsanity support forum.", 'imsanity'), $resizeResult->get_error_message())); } } } return $params; }