Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

2 participants