-
-
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
composite: top/left values can be erroneously clipped #2571
Comments
There's a lot going on here. Please can you provide minimal, standalone code where sharp is the only dependency as well as sample input images that fail in this manner. (It also looks like you've added Cloudinary secrets in the public codesandbox so you may need to revoke those.) |
Hi, thanks for your response. Thank you for the tipoff about hiding the Cloudinary secrets. This issue is part of a much larger project, so I felt it prudent to include some level of context in my question, so it would be clear what the intended functionality is. I tried to keep the explanation as concise as possible, it seems perhaps I should have pared it down even more. To that same end, I felt it prudent that the previously included CodeSandbox should retain as much pared-down functionality as possible, so that the problem could be seen in its proper context. Here is an additional Sandbox that's been pared down even more.. It was necessary to retain one canvas, along with Multer, because that is where the input buffer for Sharp comes from. One of the two input buffers has been stored as a file; the other must come from the canvas. Storing both input buffers as files proved unfeasible due to file size limitations. Please let me know if this is sufficient, and thanks for your patience. Here are two images demonstrating the problem. There are additional screenshots for other cases in the previously linked Drive folder. |
Thank you for the simplified example, that's much clearer and I can see it's hitting this logic in sharp that clips the value of Lines 700 to 704 in 2020839
This clipping logic isn't required for most composite tasks so I think the following diff should fix this: --- a/src/pipeline.cc
+++ b/src/pipeline.cc
@@ -594,8 +594,13 @@ class PipelineWorker : public Napi::AsyncWorker {
int top;
if (composite->hasOffset) {
// Composite image at given offsets
- std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(),
- compositeImage.width(), compositeImage.height(), composite->left, composite->top);
+ if (composite->tile) {
+ std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(),
+ compositeImage.width(), compositeImage.height(), composite->left, composite->top);
+ } else {
+ left = composite->left;
+ top = composite->top;
+ } Happy to accept a PR with this change and a unit test, if you're able. |
Thanks for looking into it! I'm new to working with PRs but I'll give it a shot and see what the result is, and I'll get back to you! |
Hi, thanks for waiting, I've been busy with my day job and didn't have an opportunity to dive into this till today. As I mentioned, I'm new to working with PRs so I wanted to get clarification on a couple things.
|
It looks like https://github.com/SHG42/sharp/commit/b78b95b7d1d746e99524aa034e538dc115e682e9 has copied the |
I've just added a note about the need to use the Thanks for attempting to tackle this - please do let me know if you need any more help. |
Oh, interesting! I'll take another shot at it, thanks! |
Well, this was my first encounter with C++, but I was able to successfully make the changes and run |
Perhaps you could copy your modified, compiled |
It worked! That solves the bug! What is the next step for the PR? |
Fixes bug where certain input values for top/left parameters in composite can conflict with clipping logic, resulting in inaccurate alignment in output.
v0.28.0 now available, thank you very much for both reporting and fixing this. |
What are you trying to achieve?
Extract image data from a 900x700px KonvaJS stage with layered canvases, send to server and composite the layer data buffers with another image data buffer for a sprite that was created on a separate, single-canvas 500x500px Konva stage. On the backend, Sharp receives the most recent buffers from both stages and "sandwiches" the buffer from the smaller stage in between the two buffers from the larger stage. I am attempting to use the absolute position of a sprite on the larger canvas to set the top/left parameters for the composite function.
Sharp returns a buffer which is then passed to an upload method for Cloudinary, which creates the final png file upon upload.
Extra details: the smaller stage ("creator stage") allows for the creation of a game sprite, and the larger stage ("equip stage") allows the user to equip items in front of and behind the sprite to create a scene. On the equip stage, the base sprite is loaded by itself onto a middle canvas layer, and the user can drag it around to position it relative to its items (for instance, standing on top of a fallen log or next to a lake). On form-submit from the equip page, the absolute position of the base sprite on the equip stage is retained in the sprite's MongoDB document to be used as the top/left parameter in the composite function.
The problem: In cases where the base sprite's bounds went past the equip canvas's bottom bound or right-side bound, the sprite's positioning in the composited png is incorrect. To my eye, it looks like the base sprite in the composite is being pushed up and/or left by whatever amount its bounding box has gone past the canvas's bottom or right bounds.
Have you searched for similar questions?
Yes, here and on StackOverflow. The problem is that I can't tell where the issue is coming from. It could be coming from Sharp, KonvaJS, the Cloudinary upload processing, or my code. There are no errors thrown at any point. Console logs at every step along the way haven't been conclusive enough to narrow down what part of the process is at fault. I've searched for solutions relating to each step and none have helped.
Are you able to provide a minimal, standalone code sample that demonstrates this question?
This CodeSandbox replicates the functionality of the main project as closely as possible but without database functionality. If the database could be a factor in the problem, a link can be provided upon request to view the full source code.
Are you able to provide a sample image that helps explain the question?
Here is a Drive folder containing screenshots for all cases.
The text was updated successfully, but these errors were encountered: