Move thumbnail algorithm mainly to ImageFile class

This commit is contained in:
Mikael Nordfeldth 2015-03-04 13:12:42 +01:00
parent dcfb813066
commit a4af51b5ba
2 changed files with 76 additions and 57 deletions

View File

@ -420,63 +420,7 @@ class File extends Managed_DataObject
} }
} }
if ($width === null) { return $image->getFileThumbnail($width, $height, $crop);
$width = common_config('thumbnail', 'width');
$height = common_config('thumbnail', 'height');
$crop = common_config('thumbnail', 'crop');
}
if ($height === null) {
$height = $width;
$crop = true;
}
// Get proper aspect ratio width and height before lookup
// We have to do it through an ImageFile object because of orientation etc.
// Only other solution would've been to rotate + rewrite uploaded files
// which we don't want to do because we like original, untouched data!
list($width, $height, $x, $y, $w, $h) =
$image->scaleToFit($width, $height, $crop);
$params = array('file_id'=> $this->id,
'width' => $width,
'height' => $height);
$thumb = File_thumbnail::pkeyGet($params);
if ($thumb instanceof File_thumbnail) {
return $thumb;
}
$filename = $this->filehash ?: $image->filename; // Remote files don't have $this->filename
$outname = "thumb-{$this->id}-{$width}x{$height}-{$filename}." . File::guessMimeExtension($image->mimetype);
$outpath = self::path($outname);
// The boundary box for our resizing
$box = array('width'=>$width, 'height'=>$height,
'x'=>$x, 'y'=>$y,
'w'=>$w, 'h'=>$h);
// Doublecheck that parameters are sane and integers.
if ($box['width'] < 1 || $box['width'] > common_config('thumbnail', 'maxsize')
|| $box['height'] < 1 || $box['height'] > common_config('thumbnail', 'maxsize')
|| $box['w'] < 1 || $box['x'] >= $image->width
|| $box['h'] < 1 || $box['y'] >= $image->height) {
// Fail on bad width parameter. If this occurs, it's due to algorithm in ImageFile->scaleToFit
common_debug("Boundary box parameters for resize of {$image->filepath} : ".var_export($box,true));
throw new ServerException('Bad thumbnail size parameters.');
}
common_debug(sprintf('Generating a thumbnail of File id==%u of size %ux%u', $this->id, $width, $height));
// Perform resize and store into file
$image->resizeTo($outpath, $box);
// Avoid deleting the original
if ($image->getPath() != self::path($image->filename)) {
$image->unlink();
}
return File_thumbnail::saveThumbnail($this->id,
self::url($outname),
$width, $height,
$outname);
} }
public function getPath() public function getPath()

View File

@ -55,9 +55,17 @@ class ImageFile
var $animated = null; // Animated image? (has more than 1 frame). null means untested var $animated = null; // Animated image? (has more than 1 frame). null means untested
var $mimetype = null; // The _ImageFile_ mimetype, _not_ the originating File object var $mimetype = null; // The _ImageFile_ mimetype, _not_ the originating File object
protected $fileRecord = null;
function __construct($id, $filepath) function __construct($id, $filepath)
{ {
$this->id = $id; $this->id = $id;
if (!empty($this->id)) {
$this->fileRecord = File::getKV('id', $this->id);
if (!$this->fileRecord instanceof File) {
throw new ServerException('Expected File object did not exist.');
}
}
$this->filepath = $filepath; $this->filepath = $filepath;
$this->filename = basename($filepath); $this->filename = basename($filepath);
@ -542,6 +550,73 @@ class ImageFile
fclose($fh); fclose($fh);
return $count > 1; return $count > 1;
} }
public function getFileThumbnail($width, $height, $crop)
{
if (!$this->fileRecord instanceof File) {
throw new ServerException('No File object attached to this ImageFile object.');
}
if ($width === null) {
$width = common_config('thumbnail', 'width');
$height = common_config('thumbnail', 'height');
$crop = common_config('thumbnail', 'crop');
}
if ($height === null) {
$height = $width;
$crop = true;
}
// Get proper aspect ratio width and height before lookup
// We have to do it through an ImageFile object because of orientation etc.
// Only other solution would've been to rotate + rewrite uploaded files
// which we don't want to do because we like original, untouched data!
list($width, $height, $x, $y, $w, $h) = $this->scaleToFit($width, $height, $crop);
$thumb = File_thumbnail::pkeyGet(array(
'file_id'=> $this->fileRecord->id,
'width' => $width,
'height' => $height,
));
if ($thumb instanceof File_thumbnail) {
return $thumb;
}
$filename = $this->fileRecord->filehash ?: $this->filename; // Remote files don't have $this->filehash
$extension = File::guessMimeExtension($this->mimetype);
$outname = "thumb-{$this->fileRecord->id}-{$width}x{$height}-{$filename}." . $extension;
$outpath = File_thumbnail::path($outname);
// The boundary box for our resizing
$box = array('width'=>$width, 'height'=>$height,
'x'=>$x, 'y'=>$y,
'w'=>$w, 'h'=>$h);
// Doublecheck that parameters are sane and integers.
if ($box['width'] < 1 || $box['width'] > common_config('thumbnail', 'maxsize')
|| $box['height'] < 1 || $box['height'] > common_config('thumbnail', 'maxsize')
|| $box['w'] < 1 || $box['x'] >= $this->width
|| $box['h'] < 1 || $box['y'] >= $this->height) {
// Fail on bad width parameter. If this occurs, it's due to algorithm in ImageFile->scaleToFit
common_debug("Boundary box parameters for resize of {$this->filepath} : ".var_export($box,true));
throw new ServerException('Bad thumbnail size parameters.');
}
common_debug(sprintf('Generating a thumbnail of File id==%u of size %ux%u', $this->fileRecord->id, $width, $height));
// Perform resize and store into file
$this->resizeTo($outpath, $box);
// Avoid deleting the original
if ($this->getPath() != File_thumbnail::path($this->filename)) {
$this->unlink();
}
return File_thumbnail::saveThumbnail($this->fileRecord->id,
File_thumbnail::url($outname),
$width, $height,
$outname);
}
} }
//PHP doesn't (as of 2/24/2010) have an imagecreatefrombmp so conditionally define one //PHP doesn't (as of 2/24/2010) have an imagecreatefrombmp so conditionally define one