Skip to content

Commit d91b499

Browse files
committed
add sig.php example
1 parent 02d3c39 commit d91b499

File tree

5 files changed

+108
-0
lines changed

5 files changed

+108
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ All notable changes to `:vips` will be documented in this file.
66
### Added
77
- logging with PSR-3 Logger Interface [Kleis Auke Wolthuizen]
88
- switch to PSR2 formatting [Kleis Auke Wolthuizen]
9+
- add sig.php example [John Cupitt]
910

1011
### Deprecated
1112
- removed `\Enum` from enum names
File renamed without changes.
File renamed without changes.
File renamed without changes.

examples/sig.php

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
require __DIR__ . '/../vendor/autoload.php';
5+
use Jcupitt\Vips;
6+
7+
# sigmoidal contrast adjustment in php-vips
8+
9+
# This is a standard contrast adjustment technique: grey values are put through
10+
# an S-shaped curve which boosts the slope in the mid-tones and drops it for
11+
# white and black.
12+
13+
function sigmoid(float $alpha, float $beta, bool $ushort = FALSE): Vips\Image
14+
{
15+
# make a identity LUT, that is, a lut where each pixel has the value of
16+
# its index ... if you map an image through the identity, you get the
17+
# same image back again
18+
#
19+
# LUTs in libvips are just images with either the width or height set
20+
# to 1, and the "interpretation" tag set to HISTOGRAM
21+
#
22+
# if "ushort" is TRUE, we make a 16-bit LUT, ie. 0 - 65535 values;
23+
# otherwise it's 8-bit (0 - 255)
24+
$lut = Vips\Image::identity(["ushort" => $ushort]);
25+
26+
# rescale so each element is in [0, 1]
27+
$max = $lut->max();
28+
$lut = $lut->divide($max);
29+
30+
# the sigmoidal equation, see
31+
# http://www.imagemagick.org/Usage/color_mods/#sigmoidal
32+
$x = $lut->multiply(-1)->add($alpha)->multiply($beta)->exp();
33+
$y = exp($beta + 1);
34+
$t1 = $x->divide($y)->add(1);
35+
$t2 = $x->add(1)->pow(-1)->subtract(1 / $y);
36+
$result = $t1->multiply($t2);
37+
38+
# rescale back to 0 - 255 or 0 - 65535
39+
$result = $result->multiply($max);
40+
41+
# and get the format right ... $result will be a float image after all
42+
# that maths, but we want uchar or ushort
43+
$result = $result->cast($ushort ?
44+
Vips\BandFormat::USHORT : Vips\BandFormat::UCHAR);
45+
46+
return $result;
47+
}
48+
49+
# Apply to RGB. This takes no account of image gamma, and applies the
50+
# contrast boost to R, G and B bands, thereby also boosting colourfulness.
51+
function sigRGB(Vips\Image $image, float $alpha, float $beta): Vips\Image
52+
{
53+
$lut = sigmoid($alpha, $beta, $image->format == Vips\BandFormat::USHORT);
54+
55+
return $image->maplut($lut);
56+
}
57+
58+
# Fancier: apply to L of CIELAB. This will change luminance equally, and will
59+
# not change colourfulness.
60+
function sigLAB(Vips\Image $image, float $alpha, float $beta): Vips\Image
61+
{
62+
$old_interpretation = $image->interpretation;
63+
64+
# labs is CIELAB with colour values expressed as short (signed 16-bit ints)
65+
# L is in 0 - 32767
66+
$image = $image->colourspace(Vips\Interpretation::LABS);
67+
68+
# make a 16-bit LUT, then shrink by x2 to make it fit the range of L in labs
69+
$lut = sigmoid($alpha, $beta, TRUE);
70+
$lut = $lut->shrinkh(2)->multiply(0.5);
71+
$lut = $lut->cast(Vips\BandFormat::SHORT);
72+
73+
# get the L band from our labs image, map though the LUT, then reattach the
74+
# ab bands from the labs image
75+
$L = $image->extract_band(0);
76+
$AB = $image->extract_band(1, ["n" => 2]);
77+
$L = $L->maplut($lut);
78+
$image = $L->bandjoin($AB);
79+
80+
# and back to our original colourspace again (probably rgb)
81+
#
82+
# after the manipulation above, $image will just be tagged as a generic
83+
# multiband image, vips will no longer know that it's a labs, so we need to
84+
# tell colourspace what the source space is
85+
$image = $image->colourspace($old_interpretation,
86+
["source_space" => Vips\Interpretation::LABS]);
87+
88+
return $image;
89+
}
90+
91+
$im = Vips\Image::newFromFile($argv[1], ["access" => Vips\Access::SEQUENTIAL]);
92+
93+
# $beta == 10 is a large contrast boost, values below about 4 drop the contrast
94+
#
95+
# sigLAB is the fancy one, and is much slower than sigRGB
96+
$im = sigLAB($im, 0.5, 10);
97+
98+
$im->writeToFile($argv[2]);
99+
100+
/*
101+
* Local variables:
102+
* tab-width: 4
103+
* c-basic-offset: 4
104+
* End:
105+
* vim600: expandtab sw=4 ts=4 fdm=marker
106+
* vim<600: expandtab sw=4 ts=4
107+
*/

0 commit comments

Comments
 (0)