Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/files/transform/PhabricatorFileThumbnailTransform.php
12242 views
1
<?php
2
3
final class PhabricatorFileThumbnailTransform
4
extends PhabricatorFileImageTransform {
5
6
const TRANSFORM_PROFILE = 'profile';
7
const TRANSFORM_PINBOARD = 'pinboard';
8
const TRANSFORM_THUMBGRID = 'thumbgrid';
9
const TRANSFORM_PREVIEW = 'preview';
10
const TRANSFORM_WORKCARD = 'workcard';
11
12
private $name;
13
private $key;
14
private $dstX;
15
private $dstY;
16
private $scaleUp;
17
18
public function setName($name) {
19
$this->name = $name;
20
return $this;
21
}
22
23
public function setKey($key) {
24
$this->key = $key;
25
return $this;
26
}
27
28
public function setDimensions($x, $y) {
29
$this->dstX = $x;
30
$this->dstY = $y;
31
return $this;
32
}
33
34
public function setScaleUp($scale) {
35
$this->scaleUp = $scale;
36
return $this;
37
}
38
39
public function getTransformName() {
40
return $this->name;
41
}
42
43
public function getTransformKey() {
44
return $this->key;
45
}
46
47
protected function getFileProperties() {
48
$properties = array();
49
switch ($this->key) {
50
case self::TRANSFORM_PROFILE:
51
$properties['profile'] = true;
52
$properties['name'] = 'profile';
53
break;
54
}
55
return $properties;
56
}
57
58
public function generateTransforms() {
59
return array(
60
id(new PhabricatorFileThumbnailTransform())
61
->setName(pht("Profile (400px \xC3\x97 400px)"))
62
->setKey(self::TRANSFORM_PROFILE)
63
->setDimensions(400, 400)
64
->setScaleUp(true),
65
id(new PhabricatorFileThumbnailTransform())
66
->setName(pht("Pinboard (280px \xC3\x97 210px)"))
67
->setKey(self::TRANSFORM_PINBOARD)
68
->setDimensions(280, 210),
69
id(new PhabricatorFileThumbnailTransform())
70
->setName(pht('Thumbgrid (100px)'))
71
->setKey(self::TRANSFORM_THUMBGRID)
72
->setDimensions(100, null),
73
id(new PhabricatorFileThumbnailTransform())
74
->setName(pht('Preview (220px)'))
75
->setKey(self::TRANSFORM_PREVIEW)
76
->setDimensions(220, null),
77
id(new self())
78
->setName(pht('Workcard (526px)'))
79
->setKey(self::TRANSFORM_WORKCARD)
80
->setScaleUp(true)
81
->setDimensions(526, null),
82
);
83
}
84
85
public function applyTransform(PhabricatorFile $file) {
86
$this->willTransformFile($file);
87
88
list($src_x, $src_y) = $this->getImageDimensions();
89
$dst_x = $this->dstX;
90
$dst_y = $this->dstY;
91
92
$dimensions = $this->computeDimensions(
93
$src_x,
94
$src_y,
95
$dst_x,
96
$dst_y);
97
98
$copy_x = $dimensions['copy_x'];
99
$copy_y = $dimensions['copy_y'];
100
$use_x = $dimensions['use_x'];
101
$use_y = $dimensions['use_y'];
102
$dst_x = $dimensions['dst_x'];
103
$dst_y = $dimensions['dst_y'];
104
105
return $this->applyCropAndScale(
106
$dst_x,
107
$dst_y,
108
($src_x - $copy_x) / 2,
109
($src_y - $copy_y) / 2,
110
$copy_x,
111
$copy_y,
112
$use_x,
113
$use_y,
114
$this->scaleUp);
115
}
116
117
118
public function getTransformedDimensions(PhabricatorFile $file) {
119
$dst_x = $this->dstX;
120
$dst_y = $this->dstY;
121
122
// If this is transform has fixed dimensions, we can trivially predict
123
// the dimensions of the transformed file.
124
if ($dst_y !== null) {
125
return array($dst_x, $dst_y);
126
}
127
128
$src_x = $file->getImageWidth();
129
$src_y = $file->getImageHeight();
130
131
if (!$src_x || !$src_y) {
132
return null;
133
}
134
135
$dimensions = $this->computeDimensions(
136
$src_x,
137
$src_y,
138
$dst_x,
139
$dst_y);
140
141
return array($dimensions['dst_x'], $dimensions['dst_y']);
142
}
143
144
145
private function computeDimensions($src_x, $src_y, $dst_x, $dst_y) {
146
if ($dst_y === null) {
147
// If we only have one dimension, it represents a maximum dimension.
148
// The other dimension of the transform is scaled appropriately, except
149
// that we never generate images with crazily extreme aspect ratios.
150
if ($src_x < $src_y) {
151
// This is a tall, narrow image. Use the maximum dimension for the
152
// height and scale the width.
153
$use_y = $dst_x;
154
$dst_y = $dst_x;
155
156
$use_x = $dst_y * ($src_x / $src_y);
157
$dst_x = max($dst_y / 4, $use_x);
158
} else {
159
// This is a short, wide image. Use the maximum dimension for the width
160
// and scale the height.
161
$use_x = $dst_x;
162
163
$use_y = $dst_x * ($src_y / $src_x);
164
$dst_y = max($dst_x / 4, $use_y);
165
}
166
167
// In this mode, we always copy the entire source image. We may generate
168
// margins in the output.
169
$copy_x = $src_x;
170
$copy_y = $src_y;
171
} else {
172
$scale_up = $this->scaleUp;
173
174
// Otherwise, both dimensions are fixed. Figure out how much we'd have to
175
// scale the image down along each dimension to get the entire thing to
176
// fit.
177
$scale_x = ($dst_x / $src_x);
178
$scale_y = ($dst_y / $src_y);
179
180
if (!$scale_up) {
181
$scale_x = min($scale_x, 1);
182
$scale_y = min($scale_y, 1);
183
}
184
185
if ($scale_x > $scale_y) {
186
// This image is relatively tall and narrow. We're going to crop off the
187
// top and bottom.
188
$scale = $scale_x;
189
} else {
190
// This image is relatively short and wide. We're going to crop off the
191
// left and right.
192
$scale = $scale_y;
193
}
194
195
$copy_x = $dst_x / $scale;
196
$copy_y = $dst_y / $scale;
197
198
if (!$scale_up) {
199
$copy_x = min($src_x, $copy_x);
200
$copy_y = min($src_y, $copy_y);
201
}
202
203
// In this mode, we always use the entire destination image. We may
204
// crop the source input.
205
$use_x = $dst_x;
206
$use_y = $dst_y;
207
}
208
209
return array(
210
'copy_x' => $copy_x,
211
'copy_y' => $copy_y,
212
'use_x' => $use_x,
213
'use_y' => $use_y,
214
'dst_x' => $dst_x,
215
'dst_y' => $dst_y,
216
);
217
}
218
219
220
public function getDefaultTransform(PhabricatorFile $file) {
221
$x = (int)$this->dstX;
222
$y = (int)$this->dstY;
223
$name = 'image-'.$x.'x'.nonempty($y, $x).'.png';
224
225
$root = dirname(phutil_get_library_root('phabricator'));
226
$data = Filesystem::readFile($root.'/resources/builtin/'.$name);
227
228
return $this->newFileFromData($data);
229
}
230
231
}
232
233