Skip to content

Commit 47981de

Browse files
committed
add crop thumb mechanism, set default three thumbs, add get function
1 parent 5ee632e commit 47981de

File tree

1 file changed

+168
-97
lines changed

1 file changed

+168
-97
lines changed

src/FileApi.php

Lines changed: 168 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class 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

Comments
 (0)