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

Tiled composition onto resized image using fit=outside fails #3227

Closed
3 tasks done
faradaytrs opened this issue May 16, 2022 · 9 comments
Closed
3 tasks done

Tiled composition onto resized image using fit=outside fails #3227

faradaytrs opened this issue May 16, 2022 · 9 comments

Comments

@faradaytrs
Copy link

faradaytrs commented May 16, 2022

Possible bug

Is this a possible bug in a feature of sharp, unrelated to installation?

  • Running npm install sharp completes without error.
  • Running node -e "require('sharp')" completes without error.

If you cannot confirm both of these, please open an installation issue instead.

Are you using the latest version of sharp?

  • I am using the latest version of sharp as reported by npm view sharp dist-tags.latest.

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of sharp that is not the latest, please open an issue against that package instead.

What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp?

Cannot provide output because it happens in AWS lambda environment with node16 runtime. 1024mb memory.

What are the steps to reproduce?

I try to resize image and add watermark, watermark is resized before composing.

  1. First resize first image with: { width: 5000, height: 250, withoutEnlargement: true, fit: 'outside' }'
    fit=inside works fine.
  2. Resize second image (watermark) with { height: 768 }
  3. Compose them:
    {
    input: await secondImage.toBuffer(),
    tile: true,
    },
    And then i have the following error:
    (process:9): GLib-GObject-WARNING **: 03:40:16.528: value "0" of type 'gint' is invalid or out of range for property 'down' of type 'gint'
    ERROR Invoke Error {"errorType":"Error","errorMessage":"replicate: parameter down not set\n","stack":["Error: replicate: parameter down not set",""]}

What is the expected behaviour?

Expected to successfully generate image with watermark.

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem

Please provide sample image(s) that help explain this problem

first image
watermark

@faradaytrs
Copy link
Author

faradaytrs commented May 16, 2022

Watermark size is dynamicly calculated, and as i understand problem appears when resizing watermark size is large than requested original picture size:
for example i resize 1920x1920 image to { width: 500, height: 1600, withoutEnlargement: true, fit: 'outside' }
Because of fit=outside, result is expected to be 1600x1600.
So i calculate watermark to be { height: 640 }
And it fails. (Probably because watermark is 640, but requested original image resize has width:500, which is smaller.)
I confirm that it still throws error for { width: 639, height: 1600, withoutEnlargement: true, fit: 'outside' }
But it works fine for: { width: 640, height: 1600, withoutEnlargement: true, fit: 'outside' }

@faradaytrs
Copy link
Author

faradaytrs commented May 16, 2022

As i understand it's not related to fit property, i think it's common pattern when requested resize properties are smaller than size of the composited image (althought resulting image is not that small).
With fit=inside it just never happens because image is always smaller or equal than requested size.

I believe it's not expected behaviour because it doesn't throw:
ERROR Invoke Error {"errorType":"Error","errorMessage":"Image to composite must have same dimensions or smaller","stack":["Error: Image to composite must have same dimensions or smaller"]}

@lovell
Copy link
Owner

lovell commented Jun 6, 2022

for example i resize 1920x1920 image to { width: 500, height: 1600, withoutEnlargement: true, fit: 'outside' }
Because of fit=outside, result is expected to be 1600x1600.
So i calculate watermark to be { height: 640 }
And it fails.

The following works for me using the provided values:

  const first = await sharp("first.jpg")
    .resize({
      width: 500,
      height: 1600,
      withoutEnlargement: true,
      fit: "outside",
    })
    .toBuffer();

  const watermark = await sharp("watermark.png")
    .resize({ height: 640 })
    .toBuffer();

  await sharp(first)
    .composite([
      {
        input: watermark,
        tile: true,
      },
    ])
    .toFile("out.jpg");
$ file first.jpg watermark.png out.jpg 
first.jpg:     JPEG image data, JFIF standard 1.01, resolution (DPI), density 96x96, segment length 16, comment: "CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 75", baseline, precision 8, 1920x1920, components 3
watermark.png: PNG image data, 325 x 325, 8-bit/color RGBA, non-interlaced
out.jpg:       JPEG image data, baseline, precision 8, 1600x1600, components 3

I tried other combinations of the various values you provided but cannot reproduce. What changes do I need to make to my code to make it fail?

@lovell lovell added question and removed triage labels Jun 6, 2022
@faradaytrs
Copy link
Author

faradaytrs commented Jun 7, 2022

Well for your example i now get: Error: replicate: parameter across not set
For my first example ({ width: 5000, height: 250, withoutEnlargement: true, fit: 'outside' }' etc):
Error: replicate: parameter down not set

What can be a reason for such errors?
BTW i use arm64 version in amazon lambda nodejs 16 runtime.
I use precompiled libvips that sharp provides (don't modify it).

@lovell
Copy link
Owner

lovell commented Jun 7, 2022

Perhaps you could create a standalone repo with the exact code, images and dependency versions that allows someone else to reproduce.

@faradaytrs
Copy link
Author

faradaytrs commented Jun 8, 2022

Yeah i will do it when i have time, but in your example you use toBuffer() after resize of the first image and make composite with new sharp object, but in my case i directly call composite(). I guess it's the key difference between our examples.

  const watermark = await sharp("watermark.png")
    .resize({ height: 640 })
    .toBuffer();

  const first = await sharp("first.jpg")
    .resize({
      width: 500,
      height: 1600,
      withoutEnlargement: true,
      fit: "outside",
    })
    .composite([
      {
        input: watermark,
        tile: true,
      },
    ])
    .toFile("out.jpg");

@lovell
Copy link
Owner

lovell commented Jun 8, 2022

Thanks, I've been able to reproduce with your updated code sample. Commit a757185 fixes this and adds a test case based on the code in this issue, which would previously have failed.

@lovell lovell added this to the v0.30.7 milestone Jun 8, 2022
@lovell lovell changed the title Getting error when composing image [GLib-GObject-WARNING **: 03:40:16.528: value "0" of type 'gint' is invalid or out of range for property 'down' of type 'gint'] Tiled composition onto resized image using fit=outside fails Jun 8, 2022
@faradaytrs
Copy link
Author

faradaytrs commented Jun 9, 2022

Thank you for your time on this matter! I appreciate that.

@lovell
Copy link
Owner

lovell commented Jun 22, 2022

v0.30.7 now available with the fix, thanks for reporting this.

@lovell lovell closed this as completed Jun 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants