88class FileApi
99{
1010 protected $ basepath ;
11- protected $ thumb_sizes = [];
11+ protected $ thumb_sizes = [' S ' => ' 96x96 ' , ' M ' => ' 256x256 ' , ' L ' => ' 480x480 ' ];
1212
1313 public function __construct ($ basepath = '/ ' )
1414 {
@@ -23,9 +23,26 @@ public function __construct($basepath = '/')
2323 $ this ->basepath = $ basepath ;
2424 }
2525
26- public function thumbs ( $ thumb_sizes )
26+ public function get ( $ filename , $ size = null )
2727 {
28- $ this ->thumb_sizes = $ thumb_sizes ;
28+ // Cut original file name
29+ $ file = explode ('. ' , $ filename );
30+
31+ if (empty ($ size ) && \Storage::exists ($ this ->basepath . $ file [0 ] . '_L. ' . $ file [1 ])) {
32+ return $ this ->basepath . $ file [0 ] . '_L. ' . $ file [1 ];
33+ } else if (\Storage::exists ($ this ->basepath . $ file [0 ] . '_ ' . $ size . '. ' . $ file [1 ])) {
34+ return $ this ->basepath . $ file [0 ] . '_ ' . $ size . '. ' . $ file [1 ];
35+ } else {
36+ return $ this ->basepath . $ filename ;
37+ }
38+ }
39+
40+ public function thumbs ($ thumb_sizes = array ())
41+ {
42+ if (!empty ($ thumb_sizes )) {
43+ $ this ->thumb_sizes = $ thumb_sizes ;
44+ }
45+
2946 return $ this ;
3047 }
3148
@@ -35,6 +52,85 @@ public function save(UploadedFile $upload_file, $cus_name = null)
3552 return $ file ;
3653 }
3754
55+ public function getPath ($ filename )
56+ {
57+ if (mb_substr ($ this ->basepath , -1 , 1 , 'utf8 ' ) != '/ ' ) {
58+ $ this ->basepath .= '/ ' ;
59+ }
60+
61+ if (preg_match ('/^\// ' , $ filename )) {
62+ $ filename = mb_substr ($ filename , 1 , null , 'utf8 ' );
63+ }
64+
65+ return $ this ->basepath . $ filename ;
66+ }
67+
68+ public function getUrl ($ filename )
69+ {
70+ if (\Config::get ('filesystems.default ' ) == 's3 ' ) {
71+ return \Storage::getDriver ()->getAdapter ()->getClient ()->getObjectUrl (
72+ \Storage::getDriver ()->getAdapter ()->getBucket (),
73+ $ this ->basepath . $ filename
74+ );
75+ } else {
76+ return $ this ->basepath . $ filename ;
77+ }
78+ }
79+
80+ public function getResponse ($ filename , $ headers = [])
81+ {
82+ try {
83+ $ path = $ this ->basepath . $ filename ;
84+ $ file = \Storage::get ($ path );
85+ $ filetime = \Storage::lastModified ($ path );
86+ $ etag = md5 ($ filetime );
87+ $ time = date ('r ' , $ filetime );
88+ $ expires = date ('r ' , $ filetime + 3600 );
89+ if (trim (\Request::header ('If-None-Match ' ), '\'\" ' ) != $ etag ||
90+ new \DateTime (\Request::header ('If-Modified-Since ' )) != new \DateTime ($ time )
91+ ) {
92+ return response ($ file , 200 , $ headers )->header ('Content-Type ' , \Storage::mimeType ($ path ))
93+ ->setEtag ($ etag )
94+ ->setLastModified (new \DateTime ($ time ))
95+ ->setExpires (new \DateTime ($ expires ))
96+ ->setPublic ();
97+ }
98+
99+ return response (null , 304 , $ headers )
100+ ->setEtag ($ etag )
101+ ->setLastModified (new \DateTime ($ time ))
102+ ->setExpires (new \DateTime ($ expires ))
103+ ->setPublic ();
104+ } catch (FileNotFoundException $ e ) {
105+ abort (404 );
106+ } catch (\Illuminate \Contracts \Filesystem \FileNotFoundException $ e ) {
107+ abort (404 );
108+ }
109+ }
110+
111+ public function drop ($ filename )
112+ {
113+ // Cut original file name
114+ $ dot = strpos ($ filename , '. ' );
115+ $ origin_name = substr ($ filename , 0 , $ dot );
116+
117+ // Find all images in basepath
118+ $ allFiles = \Storage::files ($ this ->basepath );
119+ $ files = array_filter ($ allFiles , function ($ file ) use ($ origin_name )
120+ {
121+ return preg_match ('/^(.*) ' .$ origin_name .'(.*)$/ ' , $ file );
122+ });
123+
124+ // Delete original image and thumbnails
125+ foreach ($ files as $ file ) {
126+ \Storage::delete ($ file );
127+ }
128+ }
129+
130+ /********************************************
131+ *********** Private Functions *************
132+ ********************************************/
133+
38134 private function moveFile ($ upload_file , $ cus_name )
39135 {
40136 $ suffix = $ upload_file ->getClientOriginalExtension ();
@@ -62,41 +158,7 @@ private function moveFile($upload_file, $cus_name)
62158 return $ filename ;
63159 }
64160
65- public function saveThumb ($ img , $ original_name , $ suffix )
66- {
67- foreach ($ this ->thumb_sizes as $ size ) {
68- $ width = imagesx ($ img );
69- $ height = imagesy ($ img );
70-
71- $ arr_size = explode ('x ' , $ size );
72- $ thumb_width = (int )$ arr_size [0 ];
73- $ thumb_height = (int )$ arr_size [1 ];
74-
75- $ thumb_name = $ this ->basepath . $ original_name . '_ ' . $ size . '. ' . $ suffix ;
76- $ main_image = $ original_name . '. ' . $ suffix ;
77- $ tmp_filename = 'tmp/ ' . $ main_image ;
78-
79- // create a new temporary thumbnail image
80- $ tmp_thumb = imagecreatetruecolor ($ thumb_width , $ thumb_height );
81-
82- // copy and resize original image into thumbnail image
83- imagecopyresized ($ tmp_thumb , $ img , 0 , 0 , 0 , 0 , $ thumb_width , $ thumb_height , $ width , $ height );
84-
85- // save tmp image
86- \Storage::disk ('local ' )->put ($ tmp_filename , \Storage::get ($ this ->basepath . $ main_image ));
87- $ tmp_path = \Storage::disk ('local ' )->getDriver ()->getAdapter ()->getPathPrefix ();
88-
89- // save thumbnail image
90- imagepng ($ tmp_thumb , $ tmp_path . $ tmp_filename );
91- $ tmp_file = \Storage::disk ('local ' )->get ($ tmp_filename );
92- \Storage::put ($ thumb_name , $ tmp_file );
93-
94- // remove tmp image
95- \Storage::disk ('local ' )->delete ($ tmp_filename );
96- }
97- }
98-
99- public function setTmpImage ($ upload_file )
161+ private function setTmpImage ($ upload_file )
100162 {
101163 $ image_types = array ('image/png ' , 'image/gif ' , 'image/jpeg ' , 'image/jpg ' );
102164
@@ -136,78 +198,87 @@ public function setTmpImage($upload_file)
136198 }
137199 }
138200
139- public function getPath ( $ filename )
201+ private function saveThumb ( $ img , $ original_name , $ suffix )
140202 {
141- if (mb_substr ($ this ->basepath , -1 , 1 , 'utf8 ' ) != '/ ' ) {
142- $ this ->basepath .= '/ ' ;
143- }
203+ foreach ($ this ->thumb_sizes as $ size_code => $ size ) {
204+ if (is_int ($ size_code ) && $ size_code < count ($ this ->thumb_sizes )) {
205+ $ size_name = $ size ;
206+ } else {
207+ $ size_name = $ size_code ;
208+ }
144209
145- if ( preg_match ( ' /^\// ' , $ filename )) {
146- return $ this -> basepath . mb_substr ( $ filename , 1 , null , ' utf8 ' ) ;
147- }
210+ $ thumb_name = $ this -> basepath . $ original_name . ' _ ' . $ size_name . ' . ' . $ suffix ;
211+ $ main_image = $ original_name . ' . ' . $ suffix ;
212+ $ tmp_filename = ' tmp/ ' . $ main_image ;
148213
149- return $ this ->basepath . $ filename ;
150- }
214+ $ tmp_thumb = $ this ->resizeThumb ($ img , $ size );
151215
152- public function getUrl ($ filename )
153- {
154- if (\Config::get ('filesystems.default ' ) == 's3 ' ) {
155- return \Storage::getDriver ()->getAdapter ()->getClient ()->getObjectUrl (
156- \Storage::getDriver ()->getAdapter ()->getBucket (),
157- $ this ->basepath . $ filename
158- );
159- } else {
160- return $ this ->basepath . $ filename ;
216+ // save tmp image
217+ \Storage::disk ('local ' )->put ($ tmp_filename , \Storage::get ($ this ->basepath . $ main_image ));
218+ $ tmp_path = \Storage::disk ('local ' )->getDriver ()->getAdapter ()->getPathPrefix ();
219+
220+ // save thumbnail image
221+ imagepng ($ tmp_thumb , $ tmp_path . $ tmp_filename );
222+ $ tmp_file = \Storage::disk ('local ' )->get ($ tmp_filename );
223+ \Storage::put ($ thumb_name , $ tmp_file );
224+
225+ // remove tmp image
226+ \Storage::disk ('local ' )->delete ($ tmp_filename );
161227 }
162228 }
163229
164- public function getResponse ( $ filename , $ headers = [] )
230+ private function resizeThumb ( $ img , $ size )
165231 {
166- try {
167- $ path = $ this ->basepath . $ filename ;
168- $ file = \Storage::get ($ path );
169- $ filetime = \Storage::lastModified ($ path );
170- $ etag = md5 ($ filetime );
171- $ time = date ('r ' , $ filetime );
172- $ expires = date ('r ' , $ filetime + 3600 );
173- if (trim (\Request::header ('If-None-Match ' ), '\'\" ' ) != $ etag ||
174- new \DateTime (\Request::header ('If-Modified-Since ' )) != new \DateTime ($ time )
175- ) {
176- return response ($ file , 200 , $ headers )->header ('Content-Type ' , \Storage::mimeType ($ path ))
177- ->setEtag ($ etag )
178- ->setLastModified (new \DateTime ($ time ))
179- ->setExpires (new \DateTime ($ expires ))
180- ->setPublic ();
181- }
232+ $ width = imagesx ($ img );
233+ $ height = imagesy ($ img );
234+ $ arr_size = explode ('x ' , $ size );
235+ $ thumb_width = (int )$ arr_size [0 ];
236+ $ thumb_height = (int )$ arr_size [1 ];
182237
183- return response (null , 304 , $ headers )
184- ->setEtag ($ etag )
185- ->setLastModified (new \DateTime ($ time ))
186- ->setExpires (new \DateTime ($ expires ))
187- ->setPublic ();
188- } catch (FileNotFoundException $ e ) {
189- abort (404 );
190- } catch (\Illuminate \Contracts \Filesystem \FileNotFoundException $ e ) {
191- abort (404 );
192- }
238+ // create a new temporary thumbnail image
239+ $ tmp_thumb = imagecreatetruecolor ($ thumb_width , $ thumb_height );
240+
241+ $ img = $ this ->cropThumb ($ img , $ width , $ height , $ thumb_width , $ thumb_height );
242+
243+ // copy and resize original image into thumbnail image
244+ imagecopyresized ($ tmp_thumb , $ img , 0 , 0 , 0 , 0 , $ thumb_width , $ thumb_height , $ width , $ height );
245+
246+ return $ tmp_thumb ;
193247 }
194248
195- public function drop ( $ filename )
249+ private function cropThumb ( $ img , & $ width , & $ height , $ thumb_width , $ thumb_height )
196250 {
197- // Cut original file name
198- $ dot = strpos ($ filename , '. ' );
199- $ origin_name = substr ($ filename , 0 , $ dot );
200-
201- // Find all images in basepath
202- $ allFiles = \Storage::files ($ this ->basepath );
203- $ files = array_filter ($ allFiles , function ($ file ) use ($ origin_name )
204- {
205- return preg_match ('/^(.*) ' .$ origin_name .'(.*)$/ ' , $ file );
206- });
251+ $ image_ratio = $ height /$ width ;
252+ $ thumb_ratio = $ thumb_height /$ thumb_width ;
253+
254+ if ($ image_ratio !== $ thumb_ratio ) {
255+ if ($ image_ratio < $ thumb_ratio ) {
256+ $ new_width = $ thumb_width *$ height /$ thumb_height ;
257+
258+ $ square = [
259+ 'x ' => ($ width - $ new_width )/2 ,
260+ 'y ' => 0 ,
261+ 'width ' => $ new_width ,
262+ 'height ' => $ height
263+ ];
264+
265+ $ width = $ new_width ;
266+ } else if ($ image_ratio > $ thumb_ratio ) {
267+ $ new_height = $ thumb_height *$ width /$ thumb_width ;
268+
269+ $ square = [
270+ 'x ' => 0 ,
271+ 'y ' => ($ height - $ new_height )/2 ,
272+ 'width ' => $ width ,
273+ 'height ' => $ new_height
274+ ];
275+
276+ $ height = $ new_height ;
277+ }
207278
208- // Delete original image and thumbnails
209- foreach ($ files as $ file ) {
210- \Storage::delete ($ file );
279+ $ img = imagecrop ($ img , $ square );
211280 }
281+
282+ return $ img ;
212283 }
213284}
0 commit comments