Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
with
330 additions
and 125 deletions.
- +6 −2 wp-admin/includes/image.php
- +45 −0 wp-includes/class-wp-image-editor.php
- +51 −0 wp-includes/deprecated.php
- +15 −0 wp-includes/editors/class-wp-image-editor-base.php
- +108 −0 wp-includes/editors/class-wp-image-editor-gd.php
- +93 −0 wp-includes/editors/class-wp-image-editor-imagick.php
- +7 −123 wp-includes/media.php
- +5 −0 wp-settings.php
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
class WP_Image_Editor { | ||
|
||
final public static function get_instance( $path ) { | ||
$implementation = apply_filters( 'image_editor_class', self::choose_implementation(), $path ); | ||
|
||
if ( $implementation ) | ||
return new $implementation( $path ); | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Tests which editors are capable of supporting the request. | ||
* | ||
* @since 3.5.0 | ||
* @access private | ||
* | ||
* @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request. | ||
*/ | ||
private static function choose_implementation() { | ||
static $implementation; | ||
|
||
if ( null === $implementation ) { | ||
$request_order = apply_filters( 'wp_editors', array( 'imagick', 'gd' ) ); | ||
|
||
// Loop over each editor on each request looking for one which will serve this request's needs | ||
foreach ( $request_order as $editor ) { | ||
$class = 'WP_Image_Editor_' . $editor; | ||
|
||
// Check to see if this editor is a possibility, calls the editor statically | ||
if ( ! call_user_func( array( $class, 'test' ) ) ) | ||
continue; | ||
|
||
if( ! apply_filters( 'wp_editor_use_' . $editor, true ) ) | ||
continue; | ||
|
||
$implementation = $class; | ||
} | ||
} | ||
|
||
return $implementation; | ||
} | ||
} |
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
class WP_Image_Editor_Base { | ||
protected $file = false; | ||
protected $size = false; | ||
protected $orig_type = false; | ||
|
||
function __construct( $filename ) { | ||
$this->file = $filename; | ||
} | ||
|
||
public static function test() { | ||
return false; | ||
} | ||
} |
@@ -0,0 +1,108 @@ | ||
<?php | ||
|
||
class WP_Image_Editor_GD extends WP_Image_Editor_Base { | ||
private $image = false; | ||
|
||
function __destruct() { | ||
if ( $this->image ) { | ||
// we don't need the original in memory anymore | ||
imagedestroy( $this->image ); | ||
} | ||
} | ||
|
||
public static function test() { | ||
if ( ! extension_loaded('gd') || ! function_exists('gd_info') ) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
private function load() { | ||
if( $this->image ) | ||
return true; | ||
|
||
if ( ! file_exists( $this->file ) ) | ||
return sprintf( __('File “%s” doesn’t exist?'), $this->file ); | ||
|
||
if ( ! function_exists('imagecreatefromstring') ) | ||
return __('The GD image library is not installed.'); | ||
|
||
// Set artificially high because GD uses uncompressed images in memory | ||
@ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) ); | ||
$this->image = imagecreatefromstring( file_get_contents( $this->file ) ); | ||
|
||
if ( ! is_resource( $this->image ) ) | ||
return sprintf( __('File “%s” is not an image.'), $this->file ); | ||
|
||
$size = @getimagesize( $this->file ); | ||
if ( ! $size ) | ||
return new WP_Error( 'invalid_image', __('Could not read image size'), $this->file ); | ||
|
||
$this->size = array( 'width' => $size[0], 'height' => $size[1] ); | ||
$this->orig_type = $size[1]; | ||
|
||
return true; | ||
} | ||
|
||
public function resize( $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) { | ||
if ( ! $this->load() ) | ||
return; | ||
|
||
$dims = image_resize_dimensions( $this->size['width'], $this->size['height'], $max_w, $max_h, $crop ); | ||
if ( ! $dims ) | ||
return new WP_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 = wp_imagecreatetruecolor( $dst_w, $dst_h ); | ||
|
||
imagecopyresampled( $newimage, $this->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 == $this->orig_type && function_exists('imageistruecolor') && !imageistruecolor( $this->image ) ) | ||
imagetruecolortopalette( $newimage, false, imagecolorstotal( $this->image ) ); | ||
|
||
// $suffix will be appended to the destination filename, just before the extension | ||
if ( ! $suffix ) | ||
$suffix = "{$dst_w}x{$dst_h}"; | ||
|
||
$info = pathinfo( $this->file ); | ||
$dir = $info['dirname']; | ||
$ext = $info['extension']; | ||
$name = wp_basename( $this->file, ".$ext" ); | ||
|
||
if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) ) | ||
$dir = $_dest_path; | ||
$destfilename = "{$dir}/{$name}-{$suffix}.{$ext}"; | ||
|
||
if ( IMAGETYPE_GIF == $this->orig_type ) { | ||
if ( ! imagegif( $newimage, $destfilename ) ) | ||
return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) ); | ||
} | ||
elseif ( IMAGETYPE_PNG == $this->orig_type ) { | ||
if ( !imagepng( $newimage, $destfilename ) ) | ||
return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) ); | ||
} | ||
else { | ||
// all other formats are converted to jpg | ||
if ( 'jpg' != $ext && 'jpeg' != $ext ) | ||
$destfilename = "{$dir}/{$name}-{$suffix}.jpg"; | ||
|
||
if ( ! imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) ) | ||
return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) ); | ||
} | ||
|
||
imagedestroy( $newimage ); | ||
|
||
// Set correct file permissions | ||
$stat = stat( dirname( $destfilename ) ); | ||
$perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits | ||
@ chmod( $destfilename, $perms ); | ||
|
||
return array( | ||
'path' => $destfilename, | ||
'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $destfilename ) ), | ||
'width' => $dst_w, | ||
'height' => $dst_h | ||
); | ||
} | ||
} |
@@ -0,0 +1,93 @@ | ||
<?php | ||
|
||
class WP_Image_Editor_Imagick extends WP_Image_Editor_Base { | ||
private $image = false; | ||
|
||
public static function test() { | ||
if ( ! extension_loaded('imagick') ) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
private function load() { | ||
if ( ! file_exists( $this->file ) ) | ||
return sprintf( __('File “%s” doesn’t exist?'), $this->file ); | ||
|
||
try { | ||
$this->image = new Imagick( $this->file ); | ||
} | ||
catch ( Exception $e ) { | ||
return sprintf(__('File “%s” is not an image.'), $this->file); | ||
} | ||
|
||
if( ! $this->image->valid() ) { | ||
return sprintf(__('File “%s” is not an image.'), $this->file); | ||
} | ||
|
||
$this->size = $this->image->getImageGeometry(); | ||
$this->orig_type = $this->image->getImageFormat(); | ||
if ( ! $this->size ) | ||
return new WP_Error( 'invalid_image', __('Could not read image size'), $this->file ); | ||
|
||
return true; | ||
} | ||
|
||
public function resize( $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) { | ||
// Yes, this is forcing a load every time at the moment. | ||
// However, for multi-resize to work, it needs to do so, unless it's going to resize based on a modified image. | ||
if ( ! $this->load() ) | ||
return false; | ||
|
||
if ( ! is_object( $this->image ) ) | ||
return new WP_Error( 'error_loading_image', $this->image, $this->file ); | ||
|
||
$dims = image_resize_dimensions( $this->size['width'], $this->size['height'], $max_w, $max_h, $crop ); | ||
if ( ! $dims ) | ||
return new WP_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; | ||
|
||
if( 'JPEG' == $this->orig_type ) { | ||
$this->image->setImageCompression( imagick::COMPRESSION_JPEG ); | ||
$this->image->setImageCompressionQuality( $jpeg_quality ); | ||
} | ||
|
||
if ( $crop ) { | ||
$this->image->cropImage( $src_w, $src_h, $src_x, $src_y ); | ||
} | ||
|
||
//$this->image->thumbnailImage( $dst_w, $dst_h ); | ||
$this->image->scaleImage( $dst_w, $dst_h, true ); | ||
|
||
// $suffix will be appended to the destination filename, just before the extension | ||
if ( ! $suffix ) | ||
$suffix = "{$dst_w}x{$dst_h}"; | ||
|
||
$info = pathinfo( $this->file ); | ||
$dir = $info['dirname']; | ||
$ext = $info['extension']; | ||
$name = wp_basename( $this->file, ".$ext" ); | ||
|
||
if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) ) | ||
$dir = $_dest_path; | ||
$destfilename = "{$dir}/{$name}-{$suffix}.{$ext}"; | ||
|
||
if( apply_filters( 'wp_editors_stripimage', true ) ) { | ||
$this->image->stripImage(); | ||
} | ||
|
||
$this->image->writeImage( $destfilename ); | ||
|
||
// Set correct file permissions | ||
$stat = stat( dirname( $destfilename ) ); | ||
$perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits | ||
@ chmod( $destfilename, $perms ); | ||
|
||
return array( | ||
'path' => $destfilename, | ||
'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $destfilename ) ), | ||
'width' => $dst_w, | ||
'height' => $dst_h | ||
); | ||
} | ||
} |
Oops, something went wrong.
Copy/pasta?