-
Notifications
You must be signed in to change notification settings - Fork 204
/
aq_resizer.php
248 lines (201 loc) · 9.71 KB
/
aq_resizer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
<?php
/**
* Title : Aqua Resizer
* Description : Resizes WordPress images on the fly
* Version : 1.2.2
* Author : Syamil MJ
* Author URI : http://aquagraphite.com
* License : WTFPL - http://sam.zoy.org/wtfpl/
* Documentation : https://github.com/sy4mil/Aqua-Resizer/
*
* @param string $url - (required) must be uploaded using wp media uploader
* @param int $width - (required)
* @param int $height - (optional)
* @param bool $crop - (optional) default to soft crop
* @param bool $single - (optional) returns an array if false
* @param bool $upscale - (optional) resizes smaller images
* @uses wp_upload_dir()
* @uses image_resize_dimensions()
* @uses wp_get_image_editor()
*
* @return str|array
*/
if(!class_exists('Aq_Resize')) {
class Aq_Exception extends Exception {}
class Aq_Resize
{
/**
* The singleton instance
*/
static private $instance = null;
/**
* Should an Aq_Exception be thrown on error?
* If false (default), then the error will just be logged.
*/
public $throwOnError = false;
/**
* No initialization allowed
*/
private function __construct() {}
/**
* No cloning allowed
*/
private function __clone() {}
/**
* For your custom default usage you may want to initialize an Aq_Resize object by yourself and then have own defaults
*/
static public function getInstance() {
if(self::$instance == null) {
self::$instance = new self;
}
return self::$instance;
}
/**
* Run, forest.
*/
public function process( $url, $width = null, $height = null, $crop = null, $single = true, $upscale = false ) {
try {
// Validate inputs.
if (!$url)
throw new Aq_Exception('$url parameter is required');
if (!$width)
throw new Aq_Exception('$width parameter is required');
// Caipt'n, ready to hook.
if ( true === $upscale ) add_filter( 'image_resize_dimensions', array($this, 'aq_upscale'), 10, 6 );
// Define upload path & dir.
$upload_info = wp_upload_dir();
$upload_dir = $upload_info['basedir'];
$upload_url = $upload_info['baseurl'];
$http_prefix = "http://";
$https_prefix = "https://";
$relative_prefix = "//"; // The protocol-relative URL
/* if the $url scheme differs from $upload_url scheme, make them match
if the schemes differe, images don't show up. */
if(!strncmp($url,$https_prefix,strlen($https_prefix))){ //if url begins with https:// make $upload_url begin with https:// as well
$upload_url = str_replace($http_prefix,$https_prefix,$upload_url);
}
elseif(!strncmp($url,$http_prefix,strlen($http_prefix))){ //if url begins with http:// make $upload_url begin with http:// as well
$upload_url = str_replace($https_prefix,$http_prefix,$upload_url);
}
elseif(!strncmp($url,$relative_prefix,strlen($relative_prefix))){ //if url begins with // make $upload_url begin with // as well
$upload_url = str_replace(array( 0 => "$http_prefix", 1 => "$https_prefix"),$relative_prefix,$upload_url);
}
// Check if $img_url is local.
if ( false === strpos( $url, $upload_url ) )
throw new Aq_Exception('Image must be local: ' . $url);
// Define path of image.
$rel_path = str_replace( $upload_url, '', $url );
$img_path = $upload_dir . $rel_path;
// Check if img path exists, and is an image indeed.
if ( ! file_exists( $img_path ) or ! getimagesize( $img_path ) )
throw new Aq_Exception('Image file does not exist (or is not an image): ' . $img_path);
// Get image info.
$info = pathinfo( $img_path );
$ext = $info['extension'];
list( $orig_w, $orig_h ) = getimagesize( $img_path );
// Get image size after cropping.
$dims = image_resize_dimensions( $orig_w, $orig_h, $width, $height, $crop );
$dst_w = $dims[4];
$dst_h = $dims[5];
// Return the original image only if it exactly fits the needed measures.
if ( ! $dims || ( ( ( null === $height && $orig_w == $width ) xor ( null === $width && $orig_h == $height ) ) xor ( $height == $orig_h && $width == $orig_w ) ) ) {
$img_url = $url;
$dst_w = $orig_w;
$dst_h = $orig_h;
} else {
// Use this to check if cropped image already exists, so we can return that instead.
$suffix = "{$dst_w}x{$dst_h}";
$dst_rel_path = str_replace( '.' . $ext, '', $rel_path );
$destfilename = "{$upload_dir}{$dst_rel_path}-{$suffix}.{$ext}";
if ( ! $dims || ( true == $crop && false == $upscale && ( $dst_w < $width || $dst_h < $height ) ) ) {
// Can't resize, so return false saying that the action to do could not be processed as planned.
throw new Aq_Exception('Unable to resize image because image_resize_dimensions() failed');
}
// Else check if cache exists.
elseif ( file_exists( $destfilename ) && getimagesize( $destfilename ) ) {
$img_url = "{$upload_url}{$dst_rel_path}-{$suffix}.{$ext}";
}
// Else, we resize the image and return the new resized image url.
else {
$editor = wp_get_image_editor( $img_path );
if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $width, $height, $crop ) ) ) {
throw new Aq_Exception('Unable to get WP_Image_Editor: ' .
$editor->get_error_message() . ' (is GD or ImageMagick installed?)');
}
$resized_file = $editor->save();
if ( ! is_wp_error( $resized_file ) ) {
$resized_rel_path = str_replace( $upload_dir, '', $resized_file['path'] );
$img_url = $upload_url . $resized_rel_path;
} else {
throw new Aq_Exception('Unable to save resized image file: ' . $editor->get_error_message());
}
}
}
// Okay, leave the ship.
if ( true === $upscale ) remove_filter( 'image_resize_dimensions', array( $this, 'aq_upscale' ) );
// Return the output.
if ( $single ) {
// str return.
$image = $img_url;
} else {
// array return.
$image = array (
0 => $img_url,
1 => $dst_w,
2 => $dst_h
);
}
return $image;
}
catch (Aq_Exception $ex) {
error_log('Aq_Resize.process() error: ' . $ex->getMessage());
if ($this->throwOnError) {
// Bubble up exception.
throw $ex;
}
else {
// Return false, so that this patch is backwards-compatible.
return false;
}
}
}
/**
* Callback to overwrite WP computing of thumbnail measures
*/
function aq_upscale( $default, $orig_w, $orig_h, $dest_w, $dest_h, $crop ) {
if ( ! $crop ) return null; // Let the wordpress default function handle this.
// Here is the point we allow to use larger image size than the original one.
$aspect_ratio = $orig_w / $orig_h;
$new_w = $dest_w;
$new_h = $dest_h;
if ( ! $new_w ) {
$new_w = intval( $new_h * $aspect_ratio );
}
if ( ! $new_h ) {
$new_h = intval( $new_w / $aspect_ratio );
}
$size_ratio = max( $new_w / $orig_w, $new_h / $orig_h );
$crop_w = round( $new_w / $size_ratio );
$crop_h = round( $new_h / $size_ratio );
$s_x = floor( ( $orig_w - $crop_w ) / 2 );
$s_y = floor( ( $orig_h - $crop_h ) / 2 );
return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h );
}
}
}
if(!function_exists('aq_resize')) {
/**
* This is just a tiny wrapper function for the class above so that there is no
* need to change any code in your own WP themes. Usage is still the same :)
*/
function aq_resize( $url, $width = null, $height = null, $crop = null, $single = true, $upscale = false ) {
/* WPML Fix */
if ( defined( 'ICL_SITEPRESS_VERSION' ) ){
global $sitepress;
$url = $sitepress->convert_url( $url, $sitepress->get_default_language() );
}
/* WPML Fix */
$aq_resize = Aq_Resize::getInstance();
return $aq_resize->process( $url, $width, $height, $crop, $single, $upscale );
}
}