-
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
Trying to do in PHP what I've done in nip2 #241
Comments
Hi @gmcmicken, The "blend alpha" menu item is implemented in nip2's macro language -- if you click Toolkits / Edit you can read (and edit) the source code. It's in the repo here: It dates from way back, before libvips had What's your exact requirement? Do you just need to blend two images together with an offset? If you can provide some test data and desired output, I could help.
This one at least is easy -- just https://www.libvips.org/API/current/func-list.html Though now I check I see the description for |
Hi @jcupitt , Thanks for the help so far, when I tried invert() before and thought it didn't work it must have been before I read that each method returns a new image, and maybe I wrote the file from the original. My requirements for blending are pretty much exactly what is in nip2, settings a blend mode, and offset, and opacity. I'm layering line art drawings, one with lines, one with shading, and I'm also modifying the line one to make a third which adds weight and depth (using blur & contrast and/or other faux anti-aliasing techniques). There's no alpha in the originals. Does that help? |
Ah OK, then you can just cook up your own overlay pretty easily, it should just be a few lines of code. If you can make some sample images and an expected result it'll save me quite a bit of time writing an example. |
The shaded one would be the base, the outline one is the top layer with darken mode. The outline-filter would be some type of modified layer with an offset to shadow the lines. I would like to learn how to do the opacity even though I could work a solution without it, it would be good to have available. |
Hi again, this seems to work: #!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;
if(count($argv) != 4) {
echo("usage: ./overlay.php outline-image shading-image output-image\n");
exit(1);
}
$outline = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']);
$shading = Vips\Image::newFromFile($argv[2], ['access' => 'sequential']);
$output_filename = $argv[3];
// multiply blending
$image = $outline->divide(255)->multiply($shading);
$image->writeToFile($output_filename); So for every pixel you compute Translation is easiest with Maybe (untested): $shading = $shading
->gravity("north-west", $shading->width + 4, $shading->height + 4, ['extend' => 'copy'])
->crop(4, 4, $shading->width, $shading->height);
$image = $outline->divide(255)->multiply($shading); I noticed your PNGs are all three band -- you could use one band PNGs for a useful drop in image size.
Did you want to make the outline a little wider? It's easiest to do this with a small blur and a big contrast boost. |
Thanks, can you give me an example how to make it semi transparent? Add band 4 and adjust to 128 or something like that? (it's not for this layer, but potentially for other layers)
Yes I haven't settled on the exact technique yet, I have done a couple variations in photoshop I wasn't paying too much attention to the example I gave, I think it was gaussian r1.0 and legacy photoshop contrast 50. I'm blending the text layer in too but that won't have any thickness added.
They will be colored in practice, or perhaps themed using a color swap for the greys I haven't decided yet at which point to apply the color. Would it speed up processing or just the output size? |
It's really easy -- if you do: $outline->divide(255) Your outline image is now 0 - 1 for black to white. To make the black lines in the outlines midgrey instead, you need to add eg. 0.6. But you don't want the white parts to go over 1, so you need to scale the outline down to 0 - 0.4 instead. $opacity = 0.8;
$outline = $outline->multiply($opacity / 255)->add(1 - $opacity);
$image = $outline->multiply($shading);
$image->writeToFile($output_filename);
Ah I see. Yes, you can apply the colour near the end, it'd be a bit quicker. |
Hey sorry I went missing, thanks for your help again. I did decide to go with a colour output but if I want to target the greys now how would I use a conditional. In pseudocode it would be "if red == green == blue AND greater than 200"? |
Maybe (untested): // pixels where r == g == b
$grey_mask = $image[0]->equal($image[1])->equal(image[2]);
// pixels where r > 200
$bright_mask = $image[0]->more(200);
// AND them together
$mask = $grey_mask->andimage($bright_mask); |
Hmm I've tried your method on finding grey and I also tried to simplify but it never hits on grey for some reason... |
I don't think that will work, the code I posted is probably the best solution. |
Here's what happens when I try just the grey mask as you've demonstrated. It just grabs everything that isn't white including the coloured areas.
|
Oh duh, sorry. Of course it should be: $grey_mask = $image[0]->equal($image[1])->andimage($image[1]->equal($image[2])); (also untested) |
Sorry, could you explain what you mean in more detail? Do you want to compute the number of pixels two masks have in common? |
Exactly, ya, you got it. |
You can write something to count the non-zero pixels in an image as: function count_set($image)
{
$avg = $image->notequal(0)->avg();
return $image->width * $image->height * $avg / 255.0;
} Then it'd just be: $n_pixels_in_common = count_set($image1->andimage($image2)); |
I'm finding the learning curve to the methods in php steep and since I'm on a deadline though maybe I would ask for a bit of help. In nip2 there is Toolkit -> Filter -> Blend -> Blend Alpha, which works well for my purpose as it allows overlay mode, opacity, and offset. But I can't seem to replicate this in PHP.
Also, I know it's probably super straightforward but I also can't seem to do a photographic negative filter in PHP, I thought maybe maplut() could do it?
The text was updated successfully, but these errors were encountered: