/** * Crop an Image to a given size. * * @since 2.1.0 * * @param string|int $src_file The source file or Attachment ID. * @param int $src_x The start x position to crop from. * @param int $src_y The start y position to crop from. * @param int $src_w The width to crop. * @param int $src_h The height to crop. * @param int $dst_w The destination width. * @param int $dst_h The destination height. * @param int $src_abs Optional. If the source crop points are absolute. * @param string $dst_file Optional. The destination file to write to. * @return string|nxt_Error|false New filepath on success, nxt_Error or false on failure. */ function nxt_crop_image($src_file, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $dst_file = false) { if (is_numeric($src_file)) { // Handle int as attachment ID $src_file = get_attached_file($src_file); } $src = nxt_load_image($src_file); if (!is_resource($src)) { return new nxt_Error('error_loading_image', $src, $src_file); } $dst = nxt_imagecreatetruecolor($dst_w, $dst_h); if ($src_abs) { $src_w -= $src_x; $src_h -= $src_y; } if (function_exists('imageantialias')) { imageantialias($dst, true); } imagecopyresampled($dst, $src, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); imagedestroy($src); // Free up memory if (!$dst_file) { $dst_file = str_replace(basename($src_file), 'cropped-' . basename($src_file), $src_file); } $dst_file = preg_replace('/\\.[^\\.]+$/', '.jpg', $dst_file); if (imagejpeg($dst, $dst_file, apply_filters('jpeg_quality', 90, 'nxt_crop_image'))) { return $dst_file; } else { return false; } }
/** * Scale down an image to fit a particular size and save a new copy of the image. * * The PNG transparency will be preserved using the function, as well as the * image type. If the file going in is PNG, then the resized image is going to * be PNG. The only supported image types are PNG, GIF, and JPEG. * * Some functionality requires API to exist, so some PHP version may lose out * support. This is not the fault of NXTClass (where functionality is * downgraded, not actual defects), but of your PHP version. * * @since 2.5.0 * * @param string $file Image file path. * @param int $max_w Maximum width to resize to. * @param int $max_h Maximum height to resize to. * @param bool $crop Optional. Whether to crop image or resize. * @param string $suffix Optional. File suffix. * @param string $dest_path Optional. New image file path. * @param int $jpeg_quality Optional, default is 90. Image quality percentage. * @return mixed nxt_Error on failure. String with new destination path. */ function image_resize($file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90) { $image = nxt_load_image($file); if (!is_resource($image)) { return new nxt_Error('error_loading_image', $image, $file); } $size = @getimagesize($file); if (!$size) { return new nxt_Error('invalid_image', __('Could not read image size'), $file); } list($orig_w, $orig_h, $orig_type) = $size; $dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop); if (!$dims) { return new nxt_Error('error_getting_dimensions', __('Could not calculate resized image dimensions')); } list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims; $newimage = nxt_imagecreatetruecolor($dst_w, $dst_h); imagecopyresampled($newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); // convert from full colors to index colors, like original PNG. if (IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor($image)) { imagetruecolortopalette($newimage, false, imagecolorstotal($image)); } // we don't need the original in memory anymore imagedestroy($image); // $suffix will be appended to the destination filename, just before the extension if (!$suffix) { $suffix = "{$dst_w}x{$dst_h}"; } $info = pathinfo($file); $dir = $info['dirname']; $ext = $info['extension']; $name = nxt_basename($file, ".{$ext}"); if (!is_null($dest_path) and $_dest_path = realpath($dest_path)) { $dir = $_dest_path; } $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}"; if (IMAGETYPE_GIF == $orig_type) { if (!imagegif($newimage, $destfilename)) { return new nxt_Error('resize_path_invalid', __('Resize path invalid')); } } elseif (IMAGETYPE_PNG == $orig_type) { if (!imagepng($newimage, $destfilename)) { return new nxt_Error('resize_path_invalid', __('Resize path invalid')); } } else { // all other formats are converted to jpg $destfilename = "{$dir}/{$name}-{$suffix}.jpg"; if (!imagejpeg($newimage, $destfilename, apply_filters('jpeg_quality', $jpeg_quality, 'image_resize'))) { return new nxt_Error('resize_path_invalid', __('Resize path invalid')); } } imagedestroy($newimage); // Set correct file permissions $stat = stat(dirname($destfilename)); $perms = $stat['mode'] & 0666; //same permissions as parent folder, strip off the executable bits @chmod($destfilename, $perms); return $destfilename; }
function nxt_save_image($post_id) { $return = new stdClass(); $success = $delete = $scaled = $nocrop = false; $post = get_post($post_id); @ini_set('memory_limit', apply_filters('admin_memory_limit', nxt_MAX_MEMORY_LIMIT)); $img = load_image_to_edit($post_id, $post->post_mime_type); if (!is_resource($img)) { $return->error = esc_js(__('Unable to create new image.')); return $return; } $fwidth = !empty($_REQUEST['fwidth']) ? intval($_REQUEST['fwidth']) : 0; $fheight = !empty($_REQUEST['fheight']) ? intval($_REQUEST['fheight']) : 0; $target = !empty($_REQUEST['target']) ? preg_replace('/[^a-z0-9_-]+/i', '', $_REQUEST['target']) : ''; $scale = !empty($_REQUEST['do']) && 'scale' == $_REQUEST['do']; if ($scale && $fwidth > 0 && $fheight > 0) { $sX = imagesx($img); $sY = imagesy($img); // check if it has roughly the same w / h ratio $diff = round($sX / $sY, 2) - round($fwidth / $fheight, 2); if (-0.1 < $diff && $diff < 0.1) { // scale the full size image $dst = nxt_imagecreatetruecolor($fwidth, $fheight); if (imagecopyresampled($dst, $img, 0, 0, 0, 0, $fwidth, $fheight, $sX, $sY)) { imagedestroy($img); $img = $dst; $scaled = true; } } if (!$scaled) { $return->error = esc_js(__('Error while saving the scaled image. Please reload the page and try again.')); return $return; } } elseif (!empty($_REQUEST['history'])) { $changes = json_decode(stripslashes($_REQUEST['history'])); if ($changes) { $img = image_edit_apply_changes($img, $changes); } } else { $return->error = esc_js(__('Nothing to save, the image has not changed.')); return $return; } $meta = nxt_get_attachment_metadata($post_id); $backup_sizes = get_post_meta($post->ID, '_nxt_attachment_backup_sizes', true); if (!is_array($meta)) { $return->error = esc_js(__('Image data does not exist. Please re-upload the image.')); return $return; } if (!is_array($backup_sizes)) { $backup_sizes = array(); } // generate new filename $path = get_attached_file($post_id); $path_parts = pathinfo($path); $filename = $path_parts['filename']; $suffix = time() . rand(100, 999); if (defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE && isset($backup_sizes['full-orig']) && $backup_sizes['full-orig']['file'] != $path_parts['basename']) { if ('thumbnail' == $target) { $new_path = "{$path_parts['dirname']}/{$filename}-temp.{$path_parts['extension']}"; } else { $new_path = $path; } } else { while (true) { $filename = preg_replace('/-e([0-9]+)$/', '', $filename); $filename .= "-e{$suffix}"; $new_filename = "{$filename}.{$path_parts['extension']}"; $new_path = "{$path_parts['dirname']}/{$new_filename}"; if (file_exists($new_path)) { $suffix++; } else { break; } } } // save the full-size file, also needed to create sub-sizes if (!nxt_save_image_file($new_path, $img, $post->post_mime_type, $post_id)) { $return->error = esc_js(__('Unable to save the image.')); return $return; } if ('nothumb' == $target || 'all' == $target || 'full' == $target || $scaled) { $tag = false; if (isset($backup_sizes['full-orig'])) { if ((!defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE) && $backup_sizes['full-orig']['file'] != $path_parts['basename']) { $tag = "full-{$suffix}"; } } else { $tag = 'full-orig'; } if ($tag) { $backup_sizes[$tag] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $path_parts['basename']); } $success = update_attached_file($post_id, $new_path); $meta['file'] = _nxt_relative_upload_path($new_path); $meta['width'] = imagesx($img); $meta['height'] = imagesy($img); list($uwidth, $uheight) = nxt_constrain_dimensions($meta['width'], $meta['height'], 128, 96); $meta['hwstring_small'] = "height='{$uheight}' width='{$uwidth}'"; if ($success && ('nothumb' == $target || 'all' == $target)) { $sizes = get_intermediate_image_sizes(); if ('nothumb' == $target) { $sizes = array_diff($sizes, array('thumbnail')); } } $return->fw = $meta['width']; $return->fh = $meta['height']; } elseif ('thumbnail' == $target) { $sizes = array('thumbnail'); $success = $delete = $nocrop = true; } if (isset($sizes)) { foreach ($sizes as $size) { $tag = false; if (isset($meta['sizes'][$size])) { if (isset($backup_sizes["{$size}-orig"])) { if ((!defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE) && $backup_sizes["{$size}-orig"]['file'] != $meta['sizes'][$size]['file']) { $tag = "{$size}-{$suffix}"; } } else { $tag = "{$size}-orig"; } if ($tag) { $backup_sizes[$tag] = $meta['sizes'][$size]; } } $crop = $nocrop ? false : get_option("{$size}_crop"); $resized = image_make_intermediate_size($new_path, get_option("{$size}_size_w"), get_option("{$size}_size_h"), $crop); if ($resized) { $meta['sizes'][$size] = $resized; } else { unset($meta['sizes'][$size]); } } } if ($success) { nxt_update_attachment_metadata($post_id, $meta); update_post_meta($post_id, '_nxt_attachment_backup_sizes', $backup_sizes); if ($target == 'thumbnail' || $target == 'all' || $target == 'full') { $file_url = nxt_get_attachment_url($post_id); if ($thumb = $meta['sizes']['thumbnail']) { $return->thumbnail = path_join(dirname($file_url), $thumb['file']); } else { $return->thumbnail = "{$file_url}?w=128&h=128"; } } } else { $delete = true; } if ($delete) { $delpath = apply_filters('nxt_delete_file', $new_path); @unlink($delpath); } imagedestroy($img); $return->msg = esc_js(__('Image saved')); return $return; }