sharp
sharp copied to clipboard
Enhancement: expose vips_text to create an image containing rendered text
I was fiddling with SVG overlays, and tried a SVG containing text inside a foreignObject div, but it didn't render. My use case is to make the text fit the container dynamically. I won't be knowing the text length beforehand, but I know how wide the container will be. Here is the SVG image I am using: http://jsbin.com/jowaboluga/1/edit?html,output Since there is no support of drawing text over an image, I had to make a SVG with the text.
Is there any way to achieve the desired effect?
Hello, a quick Stack Overflow search revealed the following, which may help:
http://stackoverflow.com/questions/2938779/svg-scaling-text-to-fit-container http://stackoverflow.com/questions/283346/how-to-resize-text-in-svg-dynamically
@lovell I did look up those links already. And I believe they are not catering to my use case. I want the text to wrap by itself if it is overflowing the container - something easily achievable with foreignObject support. Anyhow, if it is not there, I will have to devise some method to make it work.
By the way, any plans to include the watermark functionality by default? https://github.com/h2non/bimg/ has the watermark support built in.
I would be more than willing to work on a patch if it is possible - need a few pointers, though.
I suspect librsvg (as used by libvips for SVG rendering) doesn't support the foreignObject extension to SVG and it's likely *magick has the same limitation.
I'd be happy to accept a PR that exposes vips_text, a wrapper around pango, for image creation. I need to think a little about how this should fit into the existing API (e.g. should work alongside #470).
I should be able to work this out and submit a PR soon. Not sure about *magick, though.
Instead of using it with #470, I think it could be used better as an extension to .overlayWith()
.
In terms of the API to expose this, I see it working a bit like the proposed "create image" helper described in https://github.com/lovell/sharp/issues/470#issuecomment-239620622
sharp({
text: {
text: string,
font: string,
width: integer,
align: string,
dpi: integer,
spacing: integer
}
})...
Please note that this is a proposed API and is not currently available.
I have implemented the text API, though not for the pencil branch.
There is a small issue, however. On my local system, if I use the text API, I can successfully write text to an image, however, if I do the same on an EC2 instance (my use case requires this), it throws an error
Error: VipsOperation: class "text" not found
at Error (native) null
and since there is no error trace logged with this error, I cannot quite understand how it is happening.
I have also tried compiling vips there and I can use vips text <out_image> <text>
giving me the correct output.
You can have a look at the code on my fork here #183cb8
Ha. It fixed by itself. Works now. I had to recompile libvips from source, though.
Hi Guys,
Would love to have this merged in the main Sharp release.
Any ETA on that?
@niravmehta I have the text API exposed in my forks, gargsms/sharp and gargsms/libvips
I was a little occupied with work lately, and never got the time to maintain my forks up-to-date to the upstreams. Moreover, sharp had quite a big overhaul in the pencil release.
You can use my forks, if they seem fine to you. I cannot guarantee it, but I will try my best to make PRs both to sharp and libvips in the coming days, maybe this week, because I happen to have the need to expose few other functionalities in sharp, notably tilt.
To use my fork of sharp, you would need to compile my libvips fork from source and replace your previous installation, if any, with it. There aren't very many changes to sharp code for the text functionality as most of the operations are handled in libvips. I need to discuss the implementation with @jcupitt, and @lovell first as I am not very certain of handling edge cases, and if it is optimal. For my purposes, it seems to work just fine, with no visible degradation in the text operation performance. I am yet to document the text API. Sorry about that. I will try and do this ASAP.
i need this too
Hello, this issue appears to have been left hanging for several months. As I also need this, I would like to repeat niravmehta's question. Any ETA for inclusion in the main release?
@NIPanag As always, happy to accept a PR implementing the suggested API or similar. As an aside, please remember requesting things like an "ETA" generally has the opposite effect in open source.
@lovell I didn't mean to pressure, just wanted to see if anything's happened since it's been quite a while since anything was posted on it. I'll see if I can implement it myself and open a PR, perhaps working off what @gargsms has already done in their fork.
Another issue to consider is getting vips text
working on Windows. I've been trying for a few days, but I've not managed it yet :( I just get a set of annoying white squares.
@jcupitt I don't have a Windows machine, perhaps I will try in a VM. I have implemented the text changes and already using them in production at my workplace. @lovell, @jcupitt I shall submit a PR within a few days. It would be a very crude PR, but it fulfills my goals. @NIPanag The delay was caused by the dependency of the sharp text API on the libvips text function. Since I never submitted the libvips PR, there is no reliable way this could have worked in sharp. I am extremely sorry for the delay. I have some free time at hand - vacation - and would send a PR soon. There's still a missing feature of gravity in the text rendering which I need to add before the PR is any usable.
@gargsms Thank you for your update, a PR would be most welcome. There is no need to apologise about perceived time pressure - please ignore this.
@gargsms Like I said above, I didn't mean to pressure anybody. Please don't stress because of my bad wording. As for windows testing, I should have free time tomorrow (the 20th) to look into it. I will certainly be able to test on Windows 7 64bit and possibly Windows 10 64bit.
Like @jcupitt i also get white squares/rectangles but on Linux (CentOS). Looks like the font/encoding is not working properly.
const watermark = new Buffer(`<svg>
<rect x="0" y="0" width="500" height="100" fill="#000" />
<text x="10" y="76" font-size="74" fill="#fff">${conf.watermarkText}</text>
</svg>`)
ctx.body = sharp(image.path)
.overlayWith(watermark, {gravity: 'southeast'})
.withMetadata()
It works fine on MacOS.
Any suggestions ... is it vips problem or missing fonts problem. I also tried with font-family="sans-serif"
but same result.
Could you try the command-line interface?
vips text x.png "hello world"
And see if x.png
has lettering in. It's always worked for me on linux / macOS, never properly on Windows. Font rendering involves at least freetype
, fontconfig
and pango
and I'm not clear which one I've not been able configure correctly. harfbuzz
, xft2
and cairo
might also be involved :(
@purepear This discussion is about exposing vips_text
but the problem you describe appears to be about text rendering inside SVG via librsvg. Please can you open a new issue for this.
Sorry @lovell I realized that a bit later. Saw the rectangles problem in google search. Anyways... my problem was there were no installed fonts on the linux server. I used text-to-svg to load a font and convert to path.
Sorry for clogging up sharp. I've made a separate issue for getting text
working on Windows.
UPDATE: I was able to finish up the code changes on my side. Since this only requires sharp to expose the libvips functions, a PR to libvips is due. I will be able to make that PR in a few days time at max (I would want to do that by the coming weekend), and upon acceptance to libvips, I will submit a PR to sharp with the test cases I am still trying to finish up on.
Hi @gargsms . I'm looking forward to this feature. Is it still in progress?
Hi all. Sorry for all the delay. I had a version of the logic implemented already, but it wasn't necessarily the best implementation that was possible. So, I had to rewrite almost all of it from scratch. I have raised https://github.com/jcupitt/libvips/pull/701 which tries to fit text in the best possible way inside a rectangle. I ended up implementing gravity as well because I needed it.
I underestimated the complexity of the task, and overguessed my availability and free time earlier. Working with Pango and scourging documentation for that has not been the smoothest experience so far.
A wrapper for text would be trivial to add in sharp. We need to wait till @jcupitt and I could work out something that works good enough for all conditions.
Awesome. Thanks for the hard work on this!
I see libvips 8.6.0 was just released. Does that mean this feature can now be implemented into sharp?
This feature is still unavailable?
I'm wondering the same thing. I need to add multiple strings in different position on an image.