mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #4410 from jonom/force-resampling
API Force resampling by default
This commit is contained in:
commit
bc8662b241
@ -70,7 +70,7 @@ class Image extends File implements Flushable {
|
|||||||
* @config
|
* @config
|
||||||
* @var bool Force all images to resample in all cases
|
* @var bool Force all images to resample in all cases
|
||||||
*/
|
*/
|
||||||
private static $force_resample = false;
|
private static $force_resample = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @config
|
* @config
|
||||||
@ -164,6 +164,33 @@ class Image extends File implements Flushable {
|
|||||||
return $this->getTag();
|
return $this->getTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the source image URL for this resource
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSourceURL() {
|
||||||
|
return parent::getURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the relative URL accessible through the web. If forced resampling is enabled
|
||||||
|
* the URL will point to an optimised file, if it is smaller than the original
|
||||||
|
*
|
||||||
|
* @uses Director::baseURL()
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getURL() {
|
||||||
|
if ($this->config()->force_resample) {
|
||||||
|
//return $resampled->getURL();
|
||||||
|
$resampled = $this->getFormattedImage('Resampled');
|
||||||
|
if ($resampled->getAbsoluteSize() < $this->getAbsoluteSize()) {
|
||||||
|
return $resampled->getURL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->getSourceURL();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File names are filtered through {@link FileNameFilter}, see class documentation
|
* File names are filtered through {@link FileNameFilter}, see class documentation
|
||||||
* on how to influence this behaviour.
|
* on how to influence this behaviour.
|
||||||
@ -232,10 +259,10 @@ class Image extends File implements Flushable {
|
|||||||
|
|
||||||
if( $widthRatio < $heightRatio ) {
|
if( $widthRatio < $heightRatio ) {
|
||||||
// Target is higher aspect ratio than image, so check width
|
// Target is higher aspect ratio than image, so check width
|
||||||
if($this->isWidth($width) && !Config::inst()->get('Image', 'force_resample')) return $this;
|
if($this->isWidth($width)) return $this;
|
||||||
} else {
|
} else {
|
||||||
// Target is wider or same aspect ratio as image, so check height
|
// Target is wider or same aspect ratio as image, so check height
|
||||||
if($this->isHeight($height) && !Config::inst()->get('Image', 'force_resample')) return $this;
|
if($this->isHeight($height)) return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Item must be regenerated
|
// Item must be regenerated
|
||||||
@ -281,7 +308,7 @@ class Image extends File implements Flushable {
|
|||||||
* @return Image
|
* @return Image
|
||||||
*/
|
*/
|
||||||
public function Fill($width, $height) {
|
public function Fill($width, $height) {
|
||||||
return $this->isSize($width, $height) && !Config::inst()->get('Image', 'force_resample')
|
return $this->isSize($width, $height)
|
||||||
? $this
|
? $this
|
||||||
: $this->getFormattedImage('Fill', $width, $height);
|
: $this->getFormattedImage('Fill', $width, $height);
|
||||||
}
|
}
|
||||||
@ -338,7 +365,7 @@ class Image extends File implements Flushable {
|
|||||||
* @return Image
|
* @return Image
|
||||||
*/
|
*/
|
||||||
public function Pad($width, $height, $backgroundColor='FFFFFF') {
|
public function Pad($width, $height, $backgroundColor='FFFFFF') {
|
||||||
return $this->isSize($width, $height) && !Config::inst()->get('Image', 'force_resample')
|
return $this->isSize($width, $height)
|
||||||
? $this
|
? $this
|
||||||
: $this->getFormattedImage('Pad', $width, $height, $backgroundColor);
|
: $this->getFormattedImage('Pad', $width, $height, $backgroundColor);
|
||||||
}
|
}
|
||||||
@ -362,7 +389,7 @@ class Image extends File implements Flushable {
|
|||||||
* @return Image
|
* @return Image
|
||||||
*/
|
*/
|
||||||
public function ScaleWidth($width) {
|
public function ScaleWidth($width) {
|
||||||
return $this->isWidth($width) && !Config::inst()->get('Image', 'force_resample')
|
return $this->isWidth($width)
|
||||||
? $this
|
? $this
|
||||||
: $this->getFormattedImage('ScaleWidth', $width);
|
: $this->getFormattedImage('ScaleWidth', $width);
|
||||||
}
|
}
|
||||||
@ -402,7 +429,7 @@ class Image extends File implements Flushable {
|
|||||||
* @return Image
|
* @return Image
|
||||||
*/
|
*/
|
||||||
public function ScaleHeight($height) {
|
public function ScaleHeight($height) {
|
||||||
return $this->isHeight($height) && !Config::inst()->get('Image', 'force_resample')
|
return $this->isHeight($height)
|
||||||
? $this
|
? $this
|
||||||
: $this->getFormattedImage('ScaleHeight', $height);
|
: $this->getFormattedImage('ScaleHeight', $height);
|
||||||
}
|
}
|
||||||
@ -469,6 +496,26 @@ class Image extends File implements Flushable {
|
|||||||
: $this;
|
: $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resample this Image to ensure quality preference is applied.
|
||||||
|
* Warning: it's possible this will produce a larger file of lower quality
|
||||||
|
*
|
||||||
|
* @return Image
|
||||||
|
*/
|
||||||
|
public function Resampled() {
|
||||||
|
return $this->getFormattedImage('Resampled');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resample this Image to apply quality preference
|
||||||
|
*
|
||||||
|
* @param Image_Backend $backend
|
||||||
|
* @return Image_Backend
|
||||||
|
*/
|
||||||
|
public function generateResampled(Image_Backend $backend){
|
||||||
|
return $backend;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize the image by preserving aspect ratio, keeping the image inside the
|
* Resize the image by preserving aspect ratio, keeping the image inside the
|
||||||
* $width and $height
|
* $width and $height
|
||||||
@ -768,7 +815,7 @@ class Image extends File implements Flushable {
|
|||||||
* @return Image
|
* @return Image
|
||||||
*/
|
*/
|
||||||
public function ResizedImage($width, $height) {
|
public function ResizedImage($width, $height) {
|
||||||
return $this->isSize($width, $height) && !Config::inst()->get('Image', 'force_resample')
|
return $this->isSize($width, $height)
|
||||||
? $this
|
? $this
|
||||||
: $this->getFormattedImage('ResizedImage', $width, $height);
|
: $this->getFormattedImage('ResizedImage', $width, $height);
|
||||||
}
|
}
|
||||||
@ -1029,6 +1076,10 @@ class Image_Cached extends Image {
|
|||||||
$this->Filename = $filename;
|
$this->Filename = $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getURL() {
|
||||||
|
return $this->getSourceURL();
|
||||||
|
}
|
||||||
|
|
||||||
public function getRelativePath() {
|
public function getRelativePath() {
|
||||||
return $this->getField('Filename');
|
return $this->getField('Filename');
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,8 @@ class ImageTest extends SapphireTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testGetTagWithTitle() {
|
public function testGetTagWithTitle() {
|
||||||
|
Config::inst()->update('Image', 'force_resample', false);
|
||||||
|
|
||||||
$image = $this->objFromFixture('Image', 'imageWithTitle');
|
$image = $this->objFromFixture('Image', 'imageWithTitle');
|
||||||
$expected = '<img src="' . Director::baseUrl()
|
$expected = '<img src="' . Director::baseUrl()
|
||||||
. 'assets/ImageTest/test_image.png" alt="This is a image Title" />';
|
. 'assets/ImageTest/test_image.png" alt="This is a image Title" />';
|
||||||
@ -78,6 +80,8 @@ class ImageTest extends SapphireTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testGetTagWithoutTitle() {
|
public function testGetTagWithoutTitle() {
|
||||||
|
Config::inst()->update('Image', 'force_resample', false);
|
||||||
|
|
||||||
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
|
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
|
||||||
$expected = '<img src="' . Director::baseUrl() . 'assets/ImageTest/test_image.png" alt="test_image" />';
|
$expected = '<img src="' . Director::baseUrl() . 'assets/ImageTest/test_image.png" alt="test_image" />';
|
||||||
$actual = $image->getTag();
|
$actual = $image->getTag();
|
||||||
@ -86,6 +90,8 @@ class ImageTest extends SapphireTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testGetTagWithoutTitleContainingDots() {
|
public function testGetTagWithoutTitleContainingDots() {
|
||||||
|
Config::inst()->update('Image', 'force_resample', false);
|
||||||
|
|
||||||
$image = $this->objFromFixture('Image', 'imageWithoutTitleContainingDots');
|
$image = $this->objFromFixture('Image', 'imageWithoutTitleContainingDots');
|
||||||
$expected = '<img src="' . Director::baseUrl()
|
$expected = '<img src="' . Director::baseUrl()
|
||||||
. 'assets/ImageTest/test.image.with.dots.png" alt="test.image.with.dots" />';
|
. 'assets/ImageTest/test.image.with.dots.png" alt="test.image.with.dots" />';
|
||||||
@ -166,58 +172,27 @@ class ImageTest extends SapphireTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that image manipulations that do not affect the resulting dimensions
|
* Tests that a URL to a resampled image is provided when force_resample is
|
||||||
* of the output image resample the file when force_resample is set to true.
|
* set to true, if the resampled file is smaller than the original.
|
||||||
*/
|
*/
|
||||||
public function testForceResample() {
|
public function testForceResample() {
|
||||||
|
$imageHQ = $this->objFromFixture('Image', 'highQualityJPEG');
|
||||||
|
$imageHQR = $imageHQ->Resampled();
|
||||||
|
$imageLQ = $this->objFromFixture('Image', 'lowQualityJPEG');
|
||||||
|
$imageLQR = $imageLQ->Resampled();
|
||||||
|
|
||||||
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
|
// Test resampled file is served when force_resample = true
|
||||||
$this->assertTrue($image->isSize(300, 300));
|
|
||||||
|
|
||||||
$origForceResample = Config::inst()->get('Image', 'force_resample');
|
|
||||||
Config::inst()->update('Image', 'force_resample', true);
|
Config::inst()->update('Image', 'force_resample', true);
|
||||||
|
$this->assertLessThan($imageHQ->getAbsoluteSize(), $imageHQR->getAbsoluteSize(), 'Resampled image is smaller than original');
|
||||||
|
$this->assertEquals($imageHQ->getURL(), $imageHQR->getSourceURL(), 'Path to a resampled image was returned by getURL()');
|
||||||
|
|
||||||
// Set width to 300 pixels
|
// Test original file is served when force_resample = true but original file is low quality
|
||||||
$imageScaleWidth = $image->ScaleWidth(300);
|
$this->assertGreaterThanOrEqual($imageLQ->getAbsoluteSize(), $imageLQR->getAbsoluteSize(), 'Resampled image is larger or same size as original');
|
||||||
$this->assertEquals($imageScaleWidth->getWidth(), 300);
|
$this->assertNotEquals($imageLQ->getURL(), $imageLQR->getSourceURL(), 'Path to the original image file was returned by getURL()');
|
||||||
$this->assertNotEquals($image->Filename, $imageScaleWidth->Filename);
|
|
||||||
|
|
||||||
// Set height to 300 pixels
|
// Test original file is served when force_resample = false
|
||||||
$imageScaleHeight = $image->ScaleHeight(300);
|
Config::inst()->update('Image', 'force_resample', false);
|
||||||
$this->assertEquals($imageScaleHeight->getHeight(), 300);
|
$this->assertNotEquals($imageHQ->getURL(), $imageHQR->getSourceURL(), 'Path to the original image file was returned by getURL()');
|
||||||
$this->assertNotEquals($image->Filename, $imageScaleHeight->Filename);
|
|
||||||
|
|
||||||
// Crop image to 300 x 300
|
|
||||||
$imageCropped = $image->Fill(300, 300);
|
|
||||||
$this->assertTrue($imageCropped->isSize(300, 300));
|
|
||||||
$this->assertNotEquals($image->Filename, $imageCropped->Filename);
|
|
||||||
|
|
||||||
// Resize (padded) to 300 x 300
|
|
||||||
$imageSized = $image->Pad(300, 300);
|
|
||||||
$this->assertTrue($imageSized->isSize(300, 300));
|
|
||||||
$this->assertNotEquals($image->Filename, $imageSized->Filename);
|
|
||||||
|
|
||||||
// Padded image 300 x 300 (same as above)
|
|
||||||
$imagePadded = $image->Pad(300, 300);
|
|
||||||
$this->assertTrue($imagePadded->isSize(300, 300));
|
|
||||||
$this->assertNotEquals($image->Filename, $imagePadded->Filename);
|
|
||||||
|
|
||||||
// Resized (stretched) to 300 x 300
|
|
||||||
$imageStretched = $image->ResizedImage(300, 300);
|
|
||||||
$this->assertTrue($imageStretched->isSize(300, 300));
|
|
||||||
$this->assertNotEquals($image->Filename, $imageStretched->Filename);
|
|
||||||
|
|
||||||
// Fit (various options)
|
|
||||||
$imageFit = $image->Fit(300, 600);
|
|
||||||
$this->assertTrue($imageFit->isSize(300, 300));
|
|
||||||
$this->assertNotEquals($image->Filename, $imageFit->Filename);
|
|
||||||
$imageFit = $image->Fit(600, 300);
|
|
||||||
$this->assertTrue($imageFit->isSize(300, 300));
|
|
||||||
$this->assertNotEquals($image->Filename, $imageFit->Filename);
|
|
||||||
$imageFit = $image->Fit(300, 300);
|
|
||||||
$this->assertTrue($imageFit->isSize(300, 300));
|
|
||||||
$this->assertNotEquals($image->Filename, $imageFit->Filename);
|
|
||||||
Config::inst()->update('Image', 'force_resample', $origForceResample);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testImageResize() {
|
public function testImageResize() {
|
||||||
|
Loading…
Reference in New Issue
Block a user