-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Apply image filters like sepia, black-white #104
Comments
Hi @vnkapoor, You can use eg. For more complex colour gradients, convert to black and white, then map through a LUT containing your gradient. For example: #!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;
// make a lut which is a smooth gradient from start colour to stop colour,
// with start and stop in CIELAB
function gradient($start, $stop)
{
$lut = Vips\Image::identity()->divide(255);
// lut * stop + (1 - lut) * start
$lut = $lut->multiply($stop)
->add($lut->multiply(-1)->add(1)->multiply($start));
$lut = $lut->colourspace('srgb', ['source_space' => 'lab']);
return $lut;
}
// various colours as CIELAB triples
$black = [0, 0, 0];
$red = [53, 80, 67];
$green = [88, -86, 83];
$blue = [32, 79, -108];
$white = [100, 0, 0];
$sepia = [32, 16, 35];
$image = Vips\Image::newFromFile($argv[1]);
$image = $image->colourspace("b-w")->maplut(gradient($sepia, $white));
$image->writeToFile($argv[2]); Running:
Turns this: Into this: |
|
@jcupitt Thank you for quick reply. I tried your above code for sepia effect. But i want to same sepia effect on my image like it's in Imagick image. I need to change in CIELAB triples for that? |
Maybe |
Okay, got it. One more thing just need to confirm $sepia = [0, 5, 50], What are 0, 5, 50 values are for is it a rgb? So can i get better idea for other effects. |
They are CIELAB coordinates. L is black to white 0 to 100, A is red to green -100 to +100, and B is blue to yellow -100 to +100. |
Okay, and can i manage brightness, contrast, saturation, hueRotation etc by using the above code which you provided or any other method for that? |
Brightness, saturation and hue could be implemented as a modulate operation. It involves a combination of converting an image to the LCH colorspace via For example: #!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips\Image;
use Jcupitt\Vips\Interpretation;
function greyscale(Image $image): Image
{
return $image->colourspace(Interpretation::B_W);
}
function sepia(Image $image): Image
{
$sepia = Image::newFromArray([
[0.3588, 0.7044, 0.1368],
[0.2990, 0.5870, 0.1140],
[0.2392, 0.4696, 0.0912]
]);
if ($image->hasAlpha()) {
// Separate alpha channel
$imageWithoutAlpha = $image->extract_band(0, ['n' => $image->bands - 1]);
$alpha = $image->extract_band($image->bands - 1, ['n' => 1]);
return $imageWithoutAlpha->recomb($sepia)->bandjoin($alpha);
}
return $image->recomb($sepia);
}
function modulate(Image $image, float $brightness = 1.0, float $saturation = 1.0, float $hue = 0.0): Image
{
$oldInterpretation = $image->interpretation;
// Normalize hue rotation to [0, 360]
$hue %= 360;
if ($hue < 0) {
$hue = 360 + $hue;
}
// Modulate brightness, saturation and hue
if ($image->hasAlpha()) {
// Separate alpha channel
$imageWithoutAlpha = $image->extract_band(0, ['n' => $image->bands - 1]);
$alpha = $image->extract_band($image->bands - 1, ['n' => 1]);
return $imageWithoutAlpha
->colourspace(Interpretation::LCH)
->linear([$brightness, $saturation, 1.0], [0.0, 0.0, $hue])
->colourspace($oldInterpretation)
->bandjoin($alpha);
}
return $image
->colourspace(Interpretation::LCH)
->linear([$brightness, $saturation, 1.0], [0.0, 0.0, $hue])
->colourspace($oldInterpretation);
}
$image = Image::newFromFile($argv[1]);
// Sepia filter.
//$image = sepia($image);
// Convert to 8-bit greyscale; 256 shades of grey.
//$image = greyscale($image);
// Decrease brightness and saturation while also hue-rotating by 90 degrees.
$image = modulate($image, 0.5, 0.5, 90);
$image->writeToFile($argv[2]); (I also added a hard-coded matrix that seems to work for a sepia-like effect) |
@kleisauke `array( "matrix" => array(0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0)), |
That seems to be the equivalent of CSS's $sepia = Image::newFromArray([
[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]
]); There is also an online playground available for JavaScript (which has a similar API as the PHP binding) if you want to experiment with this: |
Okay, Got it. |
Here's another way of doing contrast adjustment: #!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;
// make a tone map LUT ... pull shadows down, push highlights up
// there are lots of other params, see the docs
$tone = Vips\Image::tonelut(['S' => -10, 'H' => +10]);
$image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']);
// just map L of CIELAB so we change lightness but don't boost saturation
// use LABS: LAB encoded as signed short
$lab = $image->colourspace('labs');
$lab[0] = $lab[0]->maplut($tone);
$image = $lab->cast('short')->colourspace('srgb');
$image->writeToFile($argv[2]); This make an S-shaped curve and maps just L (lightness) through it. This lets you boost contrast without flattening highlights or squashing shadows. |
@jcupitt @kleisauke But o/p of my image is different with compare to imagick. Here i add my code for Technicolor effects.
//Below is the actual imgick matrix for technicolor When i am trying to below example it gives me error
|
You have five numbers in the first row of your matrix, not three. |
@jcupitt
|
Yes, it needs to be a 3x3 matrix. |
@jcupitt |
You'll need to read the imagick code and reimplement it in libvips. |
@jcupitt
|
Oh hey, that's great! Thank you for sharing, @vnkapoor. |
Hello @jcupitt
I want to add sepia, black & white, vintage etc.. effect on my image. Is there any method for apply this filters on my image.
I am trying it by using
conv
method is that method is for apply filters?The text was updated successfully, but these errors were encountered: