Closed jarodium closed 2 years ago
Hi again, I turned on "discussions" for php-vips, thanks for the suggestion.
You can make gradients by defining a distance function which varies between 0 and 1, then using start * d + end * (1 - d)
to blend between two triplets. For example:
#!/usr/bin/python3
import pyvips
start = [255, 0, 0]
end = [0, 0, 255]
x = pyvips.Image.xyz(100, 200)
x = x - [x.width / 2, x.height / 2]
d = (x[0] ** 2 + x[1] ** 2) ** 0.5
d = (d * 10).cos() / 2 + 0.5
out = d * end + (1 - d) * start
out = out.copy(interpretation="srgb")
out.write_to_file("x.png")
(python, but the php version is obvious) to make the very ugly:
You can use any colourspace for the blend -- LAB ought to be a bit smoother, you're right. You can do a LAB blend with eg.:
#!/usr/bin/python3
import pyvips
start = [100, 50, 0]
end = [50, 0, 50]
size = 512
x = pyvips.Image.xyz(size, size)
x = x - [x.width / 2, x.height / 2]
d = (x[0] ** 2 + x[1] ** 2) ** 0.5 / (2 ** 0.5 * size / 2)
out = d * end + (1 - d) * start
out = out.copy(interpretation="lab")
out.write_to_file("x.png")
Now start
and end
and the blend are in CIELAB. We tag the image as LAB at the end, and write_to_file
will automatically convert to srgb for us. It makes the (again) very ugly:
Oh huh now I look more carefully, that's almost what your php is doing. I'm not sure I understand your question, could you rephrase?
Hello @jcupitt
Thank you for taking the time for this issue.
The image below has a linear gradient ( from black to white ) which it is what i'm trying to achieve:
The gradient function is taken from #104 but I skip converting to black and white ( because I will need colors ). The function almost does what it is intended, but in my dev server, it is only using the $black and white lab triples hardcoded so I can make a control image.
I wish to change those triples to any other color pair, so I can manage them on my user's interface.
After i'm done ( if I get the conversion right ), I will prepare two images using both fxGradient and the new gradient using .XYZ and share them here.
Once again, thank you for your help Best regards
jarodium
Here's a demo prog:
#!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;
if(count($argv) != 4) {
echo("usage: ./gradient.php input-image output-image 'text to write'\n");
exit(1);
}
# make a vertical gradient from the start to end
# size it to match $image
function gradient($image, $start, $end): Vips\Image {
# a two-band image the size of $image whose pixel values are their
# coordinates
$xyz = Vips\Image::xyz($image->width, $image->height);
# the distance image: 0 - 1 for the start to the end of the gradient
$d = $xyz[1]->divide($xyz->height);
# and use it to fade the quads ... we need to tag the result as an RGB
# image
return $d
->multiply($end)
->add($d
->multiply(-1)
->add(1)
->multiply($start)
)
->copy(["interpretation" => "srgb"]);
}
$image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']);
# from transparent black at the top to solid black at the bottom
$grad = gradient($image, [0, 0, 0, 0], [0, 0, 0, 255]);
# make a text image to fit within width/height
$text = Vips\Image::text($argv[3], [
"font" => "sans",
"rgba" => true,
"width" => $image->width * 0.6,
"height" => $image->height * 0.2
]);
# layer the background image, the gradient, and the text on top of each other
# the x/y parameters position the two overlaying layers
$image = $image->composite([$grad, $text], "over", [
"x" => [0, $image->width * 0.1],
"y" => [0, $image->height / 2 - $text->height / 2]
]);
$image->writeToFile($argv[2]);
With this test image:
https://cdn.motor1.com/images/mgl/63KVE/s1/lamborghini-forsennato-concept.jpg
I can run this:
$ ./gradient.php ~/pics/lamborghini-forsennato-concept.jpg x.jpg '<span color="white">hello there!</span>'
To make:
Awesome. I will tweak the function to fine tune it with more options.
Meanwhile, I have talked to a friend of mine that is a designer and he explained it to me that I could use HSL values from HTML instead of converting Hex to RGB, so I think I can go back to the original idea of using LAB in order to provide a better gradient output, like you said.
For now I will close this issue and will post the completed function with my tweaks :)
Once again, thank you for your help Best regards jarodium
Hello,
I'm trying to create a user input gradient, in which, the user feeds html's hexcodes and then the software generates a gradient. I one of the issues here i've found the following code:
In which I call like this:
in which, my start and stop codes are rgb triples [0,0,0] and [255,0,0] which I got from @kleisauke 's useful parse function.
I figure I should make use of
in that particular order.
I would like to ask if there is an easier way to create a gradient of RGB colors and choose the amount of start color ( I suspect I should play with the add function a bit ) , this, while avoiding colorspace conversion.
Best regards
PS: I would like to also like to suggest opening up "Discussions" for the community to trade ideas... I'm starting to feel heavy conscience of having my questions here as issues :)