mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Enhance GD::greyscale to allow darker or lighter results, and change color weights for greyscale (#5332)
Tweaking the first three parameters (R, G, B) allows you to get a different mix of colors into grey, but it does not allow you to make the result lighter or darker because their total is normalized. This is quite a common operation on greyscaled images though, so I added a fourth parameter: brightness. It defaults to 100% so that it does not have any effect when not used (making this backwards compatible). $brightness = 50 will make it darker, $brightness = 150 will overlight it.
This commit is contained in:
parent
4f14175022
commit
9eac541740
@ -486,14 +486,16 @@ class GDBackend extends Object implements Image_Backend {
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the image greyscale
|
||||
* $rv = red value, defaults to 38
|
||||
* $gv = green value, defaults to 36
|
||||
* $bv = blue value, defaults to 26
|
||||
* Based (more or less entirely, with changes for readability) on code from
|
||||
* http://www.teckis.com/scriptix/thumbnails/teck.html
|
||||
* Make the image greyscale.
|
||||
* Default color weights are based on standard BT.601 (those used in PAL, NTSC and many software packages, also see
|
||||
* https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems )
|
||||
*
|
||||
* $R = red weight, defaults to 299
|
||||
* $G = green weight, defaults to 587
|
||||
* $B = blue weight, defaults to 114
|
||||
* $brightness = brightness in percentage, defaults to 100
|
||||
*/
|
||||
public function greyscale($rv=38, $gv=36, $bv=26) {
|
||||
public function greyscale($R=299, $G=587, $B=114, $brightness=100) {
|
||||
$width = $this->width;
|
||||
$height = $this->height;
|
||||
$newGD = imagecreatetruecolor($this->width, $this->height);
|
||||
@ -502,15 +504,18 @@ class GDBackend extends Object implements Image_Backend {
|
||||
imagealphablending($newGD, false);
|
||||
imagesavealpha($newGD, true);
|
||||
|
||||
$rt = $rv + $bv + $gv;
|
||||
$rr = ($rv == 0) ? 0 : 1/($rt/$rv);
|
||||
$br = ($bv == 0) ? 0 : 1/($rt/$bv);
|
||||
$gr = ($gv == 0) ? 0 : 1/($rt/$gv);
|
||||
$rt = $R + $G + $B;
|
||||
// if $rt is 0, bad parameters are provided, so result will be a black image
|
||||
$rr = $rt ? $R/$rt : 0;
|
||||
$gr = $rt ? $G/$rt : 0;
|
||||
$br = $rt ? $B/$rt : 0;
|
||||
// iterate over all pixels and make them grey
|
||||
for($dy = 0; $dy < $height; $dy++) {
|
||||
for($dx = 0; $dx < $width; $dx++) {
|
||||
$pxrgb = imagecolorat($this->gd, $dx, $dy);
|
||||
$heightgb = ImageColorsforIndex($this->gd, $pxrgb);
|
||||
$newcol = ($rr*$heightgb['red']) + ($br*$heightgb['blue']) + ($gr*$heightgb['green']);
|
||||
$newcol = min(255, $newcol*$brightness/100);
|
||||
$setcol = ImageColorAllocateAlpha($newGD, $newcol, $newcol, $newcol, $heightgb['alpha']);
|
||||
imagesetpixel($newGD, $dx, $dy, $setcol);
|
||||
}
|
||||
|
@ -91,8 +91,8 @@ class GDTest extends SapphireTest {
|
||||
}
|
||||
|
||||
// check various sample points
|
||||
$this->assertColourEquals(96, $samples[0]['red'], $tolerance);
|
||||
$this->assertColourEquals(91, $samples[2]['red'], $tolerance);
|
||||
$this->assertColourEquals(76, $samples[0]['red'], $tolerance);
|
||||
$this->assertColourEquals(149, $samples[2]['red'], $tolerance);
|
||||
$this->assertColourEquals(0, $samples[8]['red'], $tolerance);
|
||||
$this->assertColourEquals(127, $samples[9]['red'], $tolerance);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user