1
|
|
|
<?php
|
2
|
|
|
|
3
|
|
|
//@WARNING: requires Imagick!
|
4
|
|
|
|
5
|
|
|
//@FIXME: This is a *very* basic example! Check and validations still need to be done.
|
6
|
|
|
|
7
|
|
|
if(!is_dir($_SERVER['DOCUMENT_ROOT'])) {
|
8
|
|
|
$_SERVER['DOCUMENT_ROOT'] = dirname(dirname($_SERVER['SCRIPT_FILENAME']));
|
9
|
|
|
}
|
10
|
|
|
|
11
|
|
|
$sRootDirectory = $_SERVER['DOCUMENT_ROOT'];
|
12
|
|
|
|
13
|
|
|
if (isset($_SERVER['THUMBNAIL_DIRECTORY'])) {
|
14
|
|
|
$sThumbDirectory = $_SERVER['THUMBNAIL_DIRECTORY'];
|
15
|
|
|
} else {
|
16
|
|
|
$sThumbDirectory = sys_get_temp_dir() . '/.thumbs/';
|
17
|
|
|
}
|
18
|
|
|
|
19
|
|
|
if (is_dir($sThumbDirectory) === false) {
|
20
|
|
|
mkdir($sThumbDirectory);
|
21
|
|
|
}
|
22
|
|
|
|
23
|
|
|
if(isset($_GET['DEBUG']) || isset($_GET['debug']) ) {
|
24
|
|
|
define('DEBUG', true);
|
25
|
|
|
} else {
|
26
|
|
|
define('DEBUG', false);
|
27
|
|
|
}
|
28
|
|
|
|
29
|
|
|
if(isset($_GET['file'])) {
|
30
|
|
|
$sFilePath = $sRootDirectory . $_GET['file'];
|
31
|
|
|
}
|
32
|
|
|
else {
|
33
|
|
|
$sFilePath = $sThumbDirectory . 'empty.png';
|
34
|
|
|
}
|
35
|
|
|
|
36
|
|
|
try {
|
37
|
|
|
if(strlen($sFilePath) - strrpos($sFilePath, '.svg') === 4) {
|
38
|
|
|
// Display SVG directly
|
39
|
|
|
header('Content-Type: image/svg+xml');
|
40
|
|
|
readfile($sFilePath);
|
41
|
|
|
} else {
|
42
|
|
|
outputThumbnail($sFilePath, $sThumbDirectory, 200);
|
43
|
|
|
}
|
44
|
|
|
} catch(Exception $eAny) {
|
45
|
|
|
buildExceptionImage($eAny);
|
46
|
|
|
}
|
47
|
|
|
|
48
|
|
|
function outputThumbnail($p_sFilePath, $p_sThumbDirectory, $p_iImageWidth, $p_sOutputType = 'png') {
|
49
|
|
|
|
50
|
|
|
$bIOnlyKnowHowToWorkImagickByUsingTheCommandline = true;
|
51
|
|
|
|
52
|
|
|
if(!is_dir($p_sThumbDirectory)) {
|
53
|
|
|
throw new Exception('The directory to store the Thumbnails in does not exist at "'.$p_sThumbDirectory.'"');
|
54
|
|
|
}
|
55
|
|
|
elseif(!is_writable($p_sThumbDirectory)) {
|
56
|
|
|
throw new Exception('The directory to store the Thumbnails is not writable "'.$p_sThumbDirectory.'"');
|
57
|
|
|
}
|
58
|
|
|
|
59
|
|
|
//@TODO: check if file is on of following: '.gif', '.jpg', '.png', '.svg', '.tiff', '.ps', '.pdf', '.bmp', '.eps', '.psd',
|
60
|
|
|
/* for .swf support look at http://www.swftools.org/ ?
|
61
|
|
|
* for html preview, it is already possible to do to pdf... http://code.google.com/p/wkhtmltopdf/
|
62
|
|
|
* although it's a bit of a hack that might work.
|
63
|
|
|
*/
|
64
|
|
|
|
65
|
|
|
$sSaveFileName = sanitize($p_sFilePath) . '.' . $p_sOutputType;
|
66
|
|
|
$sSaveFilePath = $p_sThumbDirectory . $sSaveFileName;
|
67
|
|
|
|
68
|
|
|
if(class_exists('Imagick')) {
|
69
|
|
|
$bRefresh=false;
|
70
|
|
|
if($bRefresh === true && is_file($sSaveFilePath)) {
|
71
|
|
|
unlink($sSaveFilePath);
|
72
|
|
|
}#if
|
73
|
|
|
|
74
|
|
|
if(!is_file($sSaveFilePath)) {
|
75
|
|
|
$aSize = getimagesize($p_sFilePath);
|
76
|
|
|
// Create thumb for file
|
77
|
|
|
if($bIOnlyKnowHowToWorkImagickByUsingTheCommandline === true) {
|
78
|
|
|
// Save Locally
|
79
|
|
|
$iImageWidth = $p_iImageWidth;
|
80
|
|
|
if(isset($aSize[0]) && $aSize[0] <= $p_iImageWidth) {
|
81
|
|
|
$iImageWidth = $aSize[0];
|
82
|
|
|
}#if
|
83
|
|
|
|
84
|
|
|
$sCommand =
|
85
|
|
|
'convert \'' . urldecode($p_sFilePath) . '[0]\''
|
86
|
|
|
. ' -colorspace RGB'
|
87
|
|
|
. ' -geometry ' . $iImageWidth
|
88
|
|
|
. ' \'' . $sSaveFilePath . '\''
|
89
|
|
|
;
|
90
|
|
|
|
91
|
|
|
$aResult = executeCommand($sCommand);
|
92
|
|
|
|
93
|
|
|
if($aResult['return'] !== 0) {
|
94
|
|
|
throw new Exception('Error executing '.$aResult['stderr'] . '(full command : "'. $aResult['stdin'] .'")');
|
95
|
|
|
}#if
|
96
|
|
|
}
|
97
|
|
|
else {
|
98
|
|
|
// This probably still needs some fixing before it'll actually work :-S
|
99
|
|
|
$oImagick = new imagick( $p_sFilePath.'[0]'); // Read First Page of PDF
|
100
|
|
|
|
101
|
|
|
$oImagick->setResolution($p_iImageWidth, 0); // If 0 is provided as a width or height parameter, aspect ratio is maintained
|
102
|
|
|
|
103
|
|
|
$oImagick->setImageFormat( "png" ); // Convert to png
|
104
|
|
|
header('Content-Type: image/png'); // Send out
|
105
|
|
|
|
106
|
|
|
echo $oImagick;
|
107
|
|
|
}#if
|
108
|
|
|
}#if
|
109
|
|
|
$oImagick = new imagick($sSaveFilePath); // Read First Page
|
110
|
|
|
header('Content-Type: image/png'); // Send out
|
111
|
|
|
echo $oImagick;
|
112
|
|
|
} /** @noinspection SpellCheckingInspection */
|
113
|
|
|
elseif(function_exists('imagettfbbox') === true) {
|
114
|
|
|
throw new Exception('Currently only Imagick is supported');
|
115
|
|
|
}else {
|
116
|
|
|
throw new Exception('Either Imagick or the GD2 library need to installed on the server');
|
117
|
|
|
}#if
|
118
|
|
|
}
|
119
|
|
|
|
120
|
|
|
//@TODO: This needs to be placed somewhere more suitable
|
121
|
|
|
/*
|
122
|
|
|
* Because exec/sytem/etc. Are a bit lame in giving error feedback a workaround
|
123
|
|
|
* is required. Instead of executing commands directly, we open a stream, write
|
124
|
|
|
* the command to the stream and read whatever comes back out of the pipes.
|
125
|
|
|
*
|
126
|
|
|
* For general info on Standard input (stdin), Standard output (stdout) and
|
127
|
|
|
* Standard error (stderr) please visit:
|
128
|
|
|
* http://en.wikipedia.org/wiki/Standard_streams
|
129
|
|
|
*/
|
130
|
|
|
function executeCommand($p_sCommand, $p_sInput='') {
|
131
|
|
|
|
132
|
|
|
$rProcess = proc_open(
|
133
|
|
|
$p_sCommand
|
134
|
|
|
, array(
|
135
|
|
|
0 => array('pipe', 'r')
|
136
|
|
|
, 1 => array('pipe', 'w')
|
137
|
|
|
, 2 => array('pipe', 'w'))
|
138
|
|
|
, $aPipes
|
139
|
|
|
);
|
140
|
|
|
fwrite($aPipes[0], $p_sInput);
|
141
|
|
|
fclose($aPipes[0]);
|
142
|
|
|
|
143
|
|
|
|
144
|
|
|
$sStandardOutput = stream_get_contents($aPipes[1]);
|
145
|
|
|
fclose($aPipes[1]);
|
146
|
|
|
|
147
|
|
|
$sStandardError = stream_get_contents($aPipes[2]);
|
148
|
|
|
fclose($aPipes[2]);
|
149
|
|
|
|
150
|
|
|
$iReturn=proc_close($rProcess);
|
151
|
|
|
|
152
|
|
|
return array(
|
153
|
|
|
'stdin' => $p_sCommand
|
154
|
|
|
, 'stdout' => $sStandardOutput
|
155
|
|
|
, 'stderr' => $sStandardError
|
156
|
|
|
, 'return' => $iReturn
|
157
|
|
|
);
|
158
|
|
|
}
|
159
|
|
|
|
160
|
|
|
|
161
|
|
|
function buildExceptionImage(\Exception $ex) {
|
162
|
|
|
$aMessage = array();
|
163
|
|
|
if (DEBUG === true) {
|
164
|
|
|
$aMessage[] = 'Uncaught ' . get_class($ex);
|
165
|
|
|
$aMessage[] = ' in ' . basename($ex->getFile()) . ':' . $ex->getLine();
|
166
|
|
|
$aMessage[] = "\n";
|
167
|
|
|
}
|
168
|
|
|
$aMessage[] = ' Error: ' . $ex->getMessage() . ' ';
|
169
|
|
|
|
170
|
|
|
$message = implode("\n", $aMessage);
|
171
|
|
|
|
172
|
|
|
$rImage = drawText($message, 10, '255.0.0.0');
|
173
|
|
|
|
174
|
|
|
imagerectangle($rImage, 0, 0, \imagesx($rImage) - 1, \imagesy($rImage) - 1, imagecolorallocatealpha($rImage, 255, 0, 0, 0));
|
175
|
|
|
|
176
|
|
|
header('Content-Type: image/png');
|
177
|
|
|
imagepng($rImage);
|
178
|
|
|
imagedestroy($rImage);
|
179
|
|
|
}
|
180
|
|
|
|
181
|
|
|
function drawText($p_sText, $p_dSize, $p_sRgba, $p_iAngle=0, $p_sFontFile=null) {
|
182
|
|
|
$text = (string) $p_sText;
|
183
|
|
|
$size = (float) $p_dSize;
|
184
|
|
|
$angle = (int) $p_iAngle;
|
185
|
|
|
|
186
|
|
|
if($p_sFontFile === null) {
|
187
|
|
|
$sFontFile = __DIR__ . '/DroidSans.ttf';
|
188
|
|
|
}
|
189
|
|
|
else {
|
190
|
|
|
$sFontFile = $p_sFontFile;
|
191
|
|
|
}
|
192
|
|
|
|
193
|
|
|
if(!is_file($sFontFile)) {
|
194
|
|
|
echo 'Could not find font ' . $sFontFile;
|
195
|
|
|
die;
|
196
|
|
|
}
|
197
|
|
|
|
198
|
|
|
if (1 !== preg_match('~^([\d]+?)\.([\d]+?)\.([\d]+?)\.([\d]+?)$~', $p_sRgba)) {
|
199
|
|
|
$sRgba = '0.0.0.0';
|
200
|
|
|
}
|
201
|
|
|
else {
|
202
|
|
|
$sRgba = $p_sRgba;
|
203
|
|
|
}
|
204
|
|
|
list($r, $g, $b, $a) = explode('.', $sRgba);
|
205
|
|
|
|
206
|
|
|
$size = max(8, min(127, intval($size)));
|
207
|
|
|
$r = max(0, min(255, intval($r)));
|
208
|
|
|
$g = max(0, min(255, intval($g)));
|
209
|
|
|
$b = max(0, min(255, intval($b)));
|
210
|
|
|
$a = max(0, min(127, intval($a)));
|
211
|
|
|
|
212
|
|
|
$box = imagettfbbox($size, $angle, $sFontFile, $text);
|
213
|
|
|
$width = abs($box[4]) + abs($box[0]);// - $box[6];
|
214
|
|
|
$height = abs($box[3]) + abs($box[7]);// - $box[1];
|
215
|
|
|
$x = 0; // $width;
|
216
|
|
|
$y = $height - $box[1]; // $height;
|
217
|
|
|
$image = imagecreatetruecolor($width, $height);
|
218
|
|
|
imagesavealpha($image, true);
|
219
|
|
|
imagealphablending($image, true);
|
220
|
|
|
|
221
|
|
|
$transp = imagecolorallocatealpha($image, 255, 0, 0, 127);
|
222
|
|
|
imagefill($image, 0, 0, $transp);
|
223
|
|
|
|
224
|
|
|
$black = imagecolorallocatealpha($image, $r, $g, $b, $a);
|
225
|
|
|
imagettftext($image, $size, $angle, $x, $y, $black, $sFontFile, $text);
|
226
|
|
|
|
227
|
|
|
return $image;
|
228
|
|
|
}
|
229
|
|
|
|
230
|
|
|
function sanitize($p_sName){
|
231
|
|
|
return preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', '__'), $p_sName);
|
232
|
|
|
}
|
233
|
|
|
|
234
|
|
|
#EOF
|
235
|
|
|
|