Skip to content

affine should have a background parameter, and not have jaggy edges #58

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

Closed
chregu opened this issue Nov 16, 2017 · 14 comments
Closed

affine should have a background parameter, and not have jaggy edges #58

chregu opened this issue Nov 16, 2017 · 14 comments

Comments

@chregu
Copy link
Contributor

chregu commented Nov 16, 2017

I try to rotate an image by arbitrary angle. Basically works fine with just similarity, but the borders look pretty jagged, compared to what for example imagick produces.

Any hints to make them smoother?
With VIPS:
vips
With IMagick:
imagick

I'd also like to have a user-definable "background" layer instead of just an fully transparent alpha channel. For now I do this with:

                        $aa = $this->vips->extract_band(3);
                        $this->vips = $aa->ifthenelse($this->vips, $background);

But I assume this doesn't really work nicely, in case I happen to have smooth borders with hopefully also smoothness on the alpha channel for the rotated image. How would I put the rotated image on top of the background image (which can have an alpha channel as well)? Basically a compositeImage operation in IMagick, I assume.

@jcupitt
Copy link
Member

jcupitt commented Nov 17, 2017

I agree, the jagged edges are ugly, they should be fixed.

In the meantime, you can add a one-pixel border around the input image, the same colour as the background for similarity (ie. always black). You're right, a parameter to set the background for affine and similarity would be useful.

You can use flatten to composite an image with transparency against a background colour, would that help? It's the thing jpegsave uses to implement the background parameter there.

8.6 has a new composite operator that can merge a stack of transparent images using a set of PDF blend modes (so over, multiply, saturate etc.), which I think would be useful for you. 8.6 is sadly still not out, perhaps another week or two.

@jcupitt
Copy link
Member

jcupitt commented Nov 17, 2017

I've made this into an enhancement issue for affine, I hope that's OK.

@jcupitt jcupitt changed the title How to do smooth borders on similarity rotate affine should have a background parameter, and not have jaggy edges Nov 17, 2017
@chregu
Copy link
Contributor Author

chregu commented Nov 17, 2017

Thanks for the answer, looking forward to the enhancements.

Was also thinking about adding a border before rotating. What's the best way to do this? (I hope my questions aren't too basic, but I couldn't figure that one out)

I assume flatten doesn't help in this case, since the background can have transparency as well, which I'd like to keep. But hopefully composite will solve my problems.

@jcupitt
Copy link
Member

jcupitt commented Nov 17, 2017

Use embed to add borders:

https://jcupitt.github.io/php-vips/docs/classes/Jcupitt.Vips.ImageAutodoc.html#method_embed

The C docs have more detail:

https://jcupitt.github.io/libvips/API/current/libvips-conversion.html#vips-embed

However, I think the right place to fix this would be in libvips. Let me see if I can address this in 8.6, and then you can avoid adding ugly workarounds to your code.

@jcupitt
Copy link
Member

jcupitt commented Nov 17, 2017

There's an issue on the main libvips repo to track this improvement.

@jcupitt
Copy link
Member

jcupitt commented Nov 17, 2017

It seems to be fixed in this branch:

https://github.com/jcupitt/libvips/tree/fix-affine-jaggies

With this command:

$ vips similarity grid.png x.png --angle 30 --background 128

I see:

x

Would you be able to test this?

@chregu
Copy link
Contributor Author

chregu commented Nov 17, 2017

Thanks for the quick fix. Looks good in general, only when I use eg. black color with full transparency ([0,0,0,255] in PHP), it looks kinda wrong
29ccea

But way better than before for other cases (the above one may be a strange case anyway)

@chregu
Copy link
Contributor Author

chregu commented Nov 17, 2017

btw, can confirm that the composite works, eg:

        $image = $image->composite([$image, $insertImage], [2]);

works nicely, also with alpha channels. Looking forward to see #55 implemented to have consts for those ints.

@jcupitt
Copy link
Member

jcupitt commented Nov 18, 2017

It wasn't premultiplying alpha, which can add edges on resampling. Could you test again?

Funny how fiddly it can be to get all the edge cases out.

@jcupitt
Copy link
Member

jcupitt commented Nov 18, 2017

Oh, test image:

grid-rgba

Command:

$ vips similarity grid-rgba.png x.png --angle 30

Result:

x

@chregu
Copy link
Contributor Author

chregu commented Nov 18, 2017

The borders are fine now, but the background (apart from the direct border pixels) is now always totally transparent, even with for example ['background' => [0,0,0,255]]. On purpose, so I should composite a background in?

@jcupitt
Copy link
Member

jcupitt commented Nov 18, 2017

Groan, what an idiot, I forgot to convert the background to the pixel format of the premultiplied image. Try again, I now see:

$ vips similarity grid-rgba.png x.png --angle 30 --background "128 0 0 255"

x

@chregu
Copy link
Contributor Author

chregu commented Nov 18, 2017

perfect. thanks a lot, looking forward to 8.6

@jcupitt
Copy link
Member

jcupitt commented Nov 18, 2017

Thank you very much for testing this. I'll merge to master and add stuff for this to the test suite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants