-
-
Notifications
You must be signed in to change notification settings - Fork 1.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
Improve experience/performance when compositing >1000 images #2286
Comments
Also, notably, perhaps related, So probably, something weird is going on. |
This was reported before: #1708 |
Yes, this looks like the same stack overflow as #1470. @rpav does #1580 better suit your use case? The best we can do to avoid this is add an fixed limit on the number of images being composited at once. It's hard to know exactly what that limit should be, but I'd prefer a low value as people attempting to composite 100s of images are probably looking for #1580. In terms of performance, we'd need to try using a tool such as callgrind to see if there's any over-computation that might be solved with a libvips tile cache. |
It doesn't appear to; that appears to join a number of images in a uniform array. In my case, I'm using maxrects-packer to compute bins and sharp to composite some processed sprites into the image. At a glance, vips composite is not what I really want here, rather embed or insert. These don't appear to be available via sharp but I'm not sure. |
Presumably the following ought also produce similar results: let atlas = sharp({ ... });
await atlas.composite([ images[0] ]);
await atlas.composite([ images[1] ]); (Obviously, in the "real" case, I do Unfortunately this seems to clear the entire image every time |
For now I have written a simple pixel-by-pixel copy. This cuts runtime to the point where, running linearly, it's not even worth optimizing. With
With pixel copying:
The "Binned images" step is mostly slow due to rotating the image and re-converting it to a buffer. This conversion seems to take the vast majority of the time; caching the unrotated raw image buffer cut this from 2.9s to the current 0.1s. Blitting is the "Built atlas" step. (I'm probably doing something dumb and can cut loading down too.) In any case, if someone is having performance / crash issues with |
Hi @rpav I'm trying to do composite as well with a relatively large amount of images (i.e. stitch them together to form one big image). I have the same problems:
@lovell Do you have an idea how this could be fixed? Thanks! |
@willemmulder Oh right, I forgot to mention here, I posted my set of tile utilities. This is a pretty quick hack job and doubtless some pretty crappy JS, but you can see here for example, I'm literally doing a naive/simple pixel-by-pixel copy from one buffer to the other. For my current set of ~1500-is images, this takes ~60ms out of ~5s. The real solution to this I think would be as noted above, including |
@rpav Thanks! From what I see, the part of your util that you mentioned then is mainly meant to copy buffers? Which would enable me to do several .composite() operations in sequence, using a series of nested |
No, this doesn't change the viability of |
Ah I see 👍 Would it be possible to somehow use that for stitching together 20x20 small tiles into one big image? If so, I can probably figure out the rest myself... |
Is the stack overflow from issue #1708 also fixed now? |
@tgrajewski It's likely, yes, and you're welcome to test locally using |
v0.30.2 now available with this performance improvement. Please remember that #1580 still exists as a future possible enhancement for joining/stitching non-overlapping images. |
Are you using the latest version? Is the version currently in use as reported by
npm ls sharp
the same as the latest version as reported bynpm view sharp dist-tags.latest
?Yes... I upgraded (0.25.4), sadly same issue
What are the steps to reproduce?
I'm processing a bunch of images (1408 sprites around 16x16 or 32x16 to be exact). At somewhere between 1156 and 1393 (exact number unlikely to be relevant), this will crash with a segmentation fault. The gdb stacktrace looks something like this:
This continues for "a bit", ending as follows:
I don't think this is actually infinite recursion ... I don't know what's going on, specifically, but it will actually complete given enough stack space. I discovered this because it actually works for this image set when run in emacs's eshell! Subsequently using
ulimit -s 16384
also completes.This is however not the greatest workaround as it doesn't appear to scale.
What is the expected behaviour?
Stack usage not dependent on input size. Also not crashing.
Are you able to provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem?
Unsure .. my code looks something like:
This seems sufficient to crash it, though I haven't tried this outside of the other code that actually loads the images etc. Note that removing
.toBuffer()
is sufficient for it to not crash. This is all in anasync
lambda in anasync
main.Are you able to provide a sample image that helps explain the problem?
Specific images don't seem to be the triggering factor.
What is the output of running
npx envinfo --binaries --system
?The text was updated successfully, but these errors were encountered: