Skip to content
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

Multiple Image extraction and merging appears unnecessarily slow #1175

Closed
CalumD opened this issue Mar 31, 2018 · 4 comments
Closed

Multiple Image extraction and merging appears unnecessarily slow #1175

CalumD opened this issue Mar 31, 2018 · 4 comments
Labels

Comments

@CalumD
Copy link

CalumD commented Mar 31, 2018

Hi @lovell,

I would like to start by saying what a fantastic find your library is - and how impressed I am by your responsiveness and willingness to help the other issues here. Having also seen how many other issues you have to deal with, I note that the opening of this issue was not a whimsical decision, but I just can't seem to find the solution to the problem, and time is becoming a bit pressing. I am working on a project for university that requires the processing (extracting of certain regions and stitching) of many thousands of images.
For reference, similar issues have been thoroughly read and tried at #405 #699 #728 #864 #886 #971

The workflow is as follows:
I have a 2D array of .PNG files on the local filesystem, which make up "tiles" of a much larger image. Many requests will be made to the node server for fast on-the-fly regions of the whole image.
I know all the x/y coordinates and offsets of all base tiles, as well as the region to be extracted, and therefore the area and coordinates of the overlap to be created as a new image.
The regions to be extracted and stitched together will not overlap each other but need to be stitched side by side.
All base tiles are <1Mb in size with most ~600Kb

Approaches considered:

  1. Use sharp to load and extract the desired specific region from each base tile image, and place in a 2D Buffer object. step through to append all buffers in each row, then step through to combine all row buffers into final image.
  2. Use sharp to stitch all of the base tiles into a single large image, then do a single extraction of the desired region.
  3. Start with an empty image of the final resolution, and iterate over all related tiles adding to the canvas as I go.

I have managed to use the code and suggestions provided in the various comments mentioned above, to create a working solution but it is extremely slow - given what "little" work is actually required specifically in the case of approach 2. (The most primary reason I chose sharp was due to the toted speed up it provides over others). In working solutions so far, calls to .extend(), .toBuffer() and overlayWith() are needed but results have to be wrapped in new instances of a SharpInstance, which is where I have convinced myself from basic testing, the significant slowdown is taking place.
These are needed in order to avoid the main issue: using multiple .overlayWith() calls on the same instance only applies the last operation, and either deletes or ignores the work of previous calls.

The reason I say this appears slow and the key motivation behind this issue submit, is that the particular test case I have been working with only contains 12 base tiles, totalling 7.1Mb with the final image only resulting in 2697px by 3125px at 5.6Mb, yet it takes ~1 minute to complete with all previous working attempts.

Any input would be much appreciated - thanks,
Calum.

@lovell
Copy link
Owner

lovell commented Mar 31, 2018

If "time is becoming a bit pressing" then I'd use vips at the command line for this.

http://jcupitt.github.io/libvips/API/current/libvips-conversion.html#vips-arrayjoin

To stitch 4 images in a 2x2 arrangement:

vips arrayjoin "1.png 2.png 3.png 4.png" out.png --across 2

@CalumD
Copy link
Author

CalumD commented Apr 2, 2018

Ah, yes perhaps I was looking too tunnel vision at it,
I used vips directly and noticed a speed up of around 10x,

Thanks for the speedy reply and suggestion.

@CalumD CalumD closed this as completed Apr 2, 2018
@lovell
Copy link
Owner

lovell commented Apr 2, 2018

Great, thanks for confirming.

The work for #728 will make sharp a lot faster as it will remove the (un)premultiply round trip each time.

@mariosvlad
Copy link

hello @lovell , we are using sharp in an electron app and we have a similar scenario, is there an easy way to use libvips from the command line (node.js child_process) as you suggested but using the binaries already bundled with sharp?
thanks!

Repository owner locked and limited conversation to collaborators Apr 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants