-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Performance of ImageDraw::text() and potential use of FTC_Manager() #6618
Comments
I have another suggestion (in addition to glyph caching). The function getmask2 performs the following steps:
After Pillow 10 the deprecated fill parameter will be replaced by a direct call to the internal function. After this, the only Python function to be called between the two C functions is the decompression bomb check. If this was moved into C, the two functions could be combined to remove the duplicate call to text_layout. |
So - while it is a million miles from being ready for a library - i have some PoC code here using FreeType Cache from python. If it is useful ... https://github.com/time4tea/gopro-dashboard-overlay/blob/c_extension/gopro_overlay/freetype.py |
The code above, although still very(!) rough - is showing some interesting results so far. It is definitely not comparing apples to apples. but the performance so far makes me think it might be worth pursuing. |
It looks like the font rendering has got much faster in recent releases! - I was on 8.4.0 - upgrading to 9.2.0 speeds up my test case for pillow from 14ms to 4ms. I think fixing #6649 would significantly improve the performance of text rendering. I'm at a point where its basically working now - have a look at the above files if you're interested. This is the current timing for my experiment - time to render the string in the below image.
Here you can see some strings rendered by Pillow and my new code using FT cache - it is hard to tell them apart. Plain text is very much faster, stroked text is about twice as fast. I think this could be improved by caching the stroked glyphs- which would probably not be too hard to do, but I'm not intending to do this in a PoC right now. Hope that's interesting - if you decide you'd like to go further on using the FT cache - please give me a shout. |
#6649 has now been fixed in main. |
@nulano - yes - good observation. |
This has now been done in #7059 |
I attempted this change, but found a problem - the _imagingft extension is not connected to the C code for creating new images. I couldn't call I worked around this by passing I've created PR #7206 for the change. From my tests, it makes |
What did you do?
Used Pillow to render frames outputting to ffmpeg - in project https://github.com/time4tea/gopro-dashboard-overlay
Pillow is great!
I'm trying to render frames as quickly as possible, as there are many frames to render in a 1 or 2 hour video - even at 10 frames/second
I'm using the text facilities of Pillow to render text into an Image. I cache text images where possible - so rendering fixed text strings is very quick - however, with a dynamic text string, such as a datetime or GPS location - caching isn't so effective.
Looking at the call stack of drawing some text.. it seems to look something like:
When you call these functions a lot - as I do - it becomes clear that these functions probably do a lot of similar work - in a python profile of a run of my software (there are multiple call routes here so don't worry they don't all add up!)
Looking at imagingft.c, - they both seem to call (in my case) text_layout_raqm, which, I'm guessing calls through to FT to get the glyphs for the given string - allowing for ligatures/kerning etc.
I was wondering... FT seems to allow for glyph caching using FTC_Manager - is there any appetite for adding support for this?
I think that, in the case of rendering lots of frames of text, it has the possibility of adding quite a bit of performance. (Which is probably not a major goal for Pillow, totally fair!)
For example, rendering a compass widget using Pillow, with a few open and filled circles, lots of compass lines, and bilinear resize for AA takes about 2.6ms, but when adding in 4 characters for "N", "S","E", "W" - takes 13ms. (I could optimise this particular use case, its just an example of how the text rendering compares to the rest of Pillow)
Thanks for reading this far!
Thanks for a super library!
The text was updated successfully, but these errors were encountered: