PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 12.7
Jetpack – WP Security, Backup, Speed, & Growth v12.7
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / _inc / lib / tonesque.php

tonesque.php in Jetpack – WP Security, Backup, Speed, & Growth 12.7, at _inc/lib/tonesque.php

269 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Tonesque
4 * Grab an average color representation from an image.
5 *
6 * @author Automattic
7 * @author Matias Ventura
8 * @package automattic/jetpack
9 */
10
11 /**
12 * Color representation class.
13 */
14 class Tonesque {
15 /**
16 * Image URL.
17 *
18 * @var string
19 */
20 private $image_url = '';
21 /**
22 * Image identifier representing the image.
23 *
24 * @var null|object
25 */
26 private $image_obj = null;
27 /**
28 * Color code.
29 *
30 * @var string
31 */
32 private $color = '';
33
34 /**
35 * Constructor.
36 *
37 * @param string $image_url Image URL.
38 */
39 public function __construct( $image_url ) {
40 if ( ! class_exists( 'Jetpack_Color' ) ) {
41 require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class.color.php';
42 }
43
44 $this->image_url = esc_url_raw( $image_url );
45 $this->image_url = trim( $this->image_url );
46 /**
47 * Allows any image URL to be passed in for $this->image_url.
48 *
49 * @module theme-tools
50 *
51 * @since 2.5.0
52 *
53 * @param string $image_url The URL to any image
54 */
55 $this->image_url = apply_filters( 'tonesque_image_url', $this->image_url );
56
57 $this->image_obj = self::imagecreatefromurl( $this->image_url );
58 }
59
60 /**
61 * Get an image object from a URL.
62 *
63 * @param string $image_url Image URL.
64 *
65 * @return object|bool Image object or false if the image could not be loaded.
66 */
67 public static function imagecreatefromurl( $image_url ) {
68 $data = null;
69
70 // If it's a URL.
71 if ( preg_match( '#^https?://#i', $image_url ) ) {
72 // If it's a url pointing to a local media library url.
73 $content_url = content_url();
74 $_image_url = set_url_scheme( $image_url );
75 if ( wp_startswith( $_image_url, $content_url ) ) {
76 $_image_path = str_replace( $content_url, WP_CONTENT_DIR, $_image_url );
77 if ( file_exists( $_image_path ) ) {
78 $filetype = wp_check_filetype( $_image_path );
79 $type = $filetype['type'];
80
81 if ( wp_startswith( $type, 'image/' ) ) {
82 $data = file_get_contents( $_image_path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
83 }
84 }
85 }
86
87 if ( empty( $data ) ) {
88 $response = wp_safe_remote_get( $image_url );
89 if ( is_wp_error( $response ) ) {
90 return false;
91 }
92 $data = wp_remote_retrieve_body( $response );
93 }
94 }
95
96 // If it's a local path in our WordPress install.
97 if ( file_exists( $image_url ) ) {
98 $filetype = wp_check_filetype( $image_url );
99 $type = $filetype['type'];
100
101 if ( wp_startswith( $type, 'image/' ) ) {
102 $data = file_get_contents( $image_url ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
103 }
104 }
105
106 // Now turn it into an image and return it.
107 return imagecreatefromstring( $data );
108 }
109
110 /**
111 * Construct object from image.
112 *
113 * @param string $type Type (hex, rgb, hsv) (optional).
114 *
115 * @return string|bool color as a string formatted as $type or false if the image could not be loaded.
116 */
117 public function color( $type = 'hex' ) {
118 // Bail if there is no image to work with.
119 if ( ! $this->image_obj ) {
120 return false;
121 }
122
123 // Finds dominant color.
124 $color = self::grab_color();
125 // Passes value to Color class.
126 return self::get_color( $color, $type );
127 }
128
129 /**
130 * Grabs the color index for each of five sample points of the image
131 *
132 * @param string $type can be 'index' or 'hex'.
133 *
134 * @return array|false color indices or false if the image could not be loaded.
135 */
136 public function grab_points( $type = 'index' ) {
137 $img = $this->image_obj;
138 if ( ! $img ) {
139 return false;
140 }
141
142 $height = imagesy( $img );
143 $width = imagesx( $img );
144
145 /*
146 * Sample five points in the image
147 * based on rule of thirds and center.
148 */
149 $topy = round( $height / 3 );
150 $bottomy = round( ( $height / 3 ) * 2 );
151 $leftx = round( $width / 3 );
152 $rightx = round( ( $width / 3 ) * 2 );
153 $centery = round( $height / 2 );
154 $centerx = round( $width / 2 );
155
156 // Cast those colors into an array.
157 $points = array(
158 imagecolorat( $img, $leftx, $topy ),
159 imagecolorat( $img, $rightx, $topy ),
160 imagecolorat( $img, $leftx, $bottomy ),
161 imagecolorat( $img, $rightx, $bottomy ),
162 imagecolorat( $img, $centerx, $centery ),
163 );
164
165 if ( 'hex' === $type ) {
166 foreach ( $points as $i => $p ) {
167 $c = imagecolorsforindex( $img, $p );
168 $points[ $i ] = self::get_color(
169 array(
170 'r' => $c['red'],
171 'g' => $c['green'],
172 'b' => $c['blue'],
173 ),
174 'hex'
175 );
176 }
177 }
178
179 return $points;
180 }
181
182 /**
183 * Finds the average color of the image based on five sample points
184 *
185 * @return array|bool array with rgb color or false if the image could not be loaded.
186 */
187 public function grab_color() {
188 $img = $this->image_obj;
189 if ( ! $img ) {
190 return false;
191 }
192
193 $rgb = self::grab_points();
194
195 $r = array();
196 $g = array();
197 $b = array();
198
199 /*
200 * Process the color points
201 * Find the average representation
202 */
203 foreach ( $rgb as $color ) {
204 $index = imagecolorsforindex( $img, $color );
205 $r[] = $index['red'];
206 $g[] = $index['green'];
207 $b[] = $index['blue'];
208 }
209 $red = round( array_sum( $r ) / 5 );
210 $green = round( array_sum( $g ) / 5 );
211 $blue = round( array_sum( $b ) / 5 );
212
213 // The average color of the image as rgb array.
214 $color = array(
215 'r' => $red,
216 'g' => $green,
217 'b' => $blue,
218 );
219
220 return $color;
221 }
222
223 /**
224 * Get a Color object using /lib class.color
225 * Convert to appropriate type
226 *
227 * @param string $color Color code.
228 * @param string $type Color type (rgb, hex, hsv).
229 *
230 * @return string
231 */
232 public function get_color( $color, $type ) {
233 $c = new Jetpack_Color( $color, 'rgb' );
234 $this->color = $c;
235
236 switch ( $type ) {
237 case 'rgb':
238 $color = implode( ',', $c->toRgbInt() );
239 break;
240 case 'hex':
241 $color = $c->toHex();
242 break;
243 case 'hsv':
244 $color = implode( ',', $c->toHsvInt() );
245 break;
246 default:
247 return $c->toHex();
248 }
249
250 return $color;
251 }
252
253 /**
254 *
255 * Checks contrast against main color
256 * Gives either black or white for using with opacity
257 *
258 * @return string|bool Returns black or white or false if the image could not be loaded.
259 */
260 public function contrast() {
261 if ( ! $this->color ) {
262 return false;
263 }
264
265 $c = $this->color->getMaxContrastColor();
266 return implode( ',', $c->toRgbInt() );
267 }
268 }
269