lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
29.13k stars 1.3k forks source link

Resize, rotate and composite. #3730

Closed penchochris closed 1 year ago

penchochris commented 1 year ago

Question about an existing feature

What are you trying to achieve?

I want to resize and rotate an image over 1080p and composite it to an 1080p img. But I'm having error: [Error: Image to composite must have same dimensions or smaller]

When you searched for similar issues, what did you find that might be related?

https://github.com/lovell/sharp/issues/2378

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

 const rotated = await sharp(path)
   .rotate(rotation, { background: { r: 0, g: 0, b: 0, alpha: 0 } })
   .toBuffer(); 
  const bigImage = await sharp(rotated)
    .resize(6000, 6000, {
      fit: "fill",
      background: { r: 0, g: 0, b: 0, alpha: 0 }
   }).toBuffer();

   await sharp({
      create: {
        width: 1960,
        height: 1080,
        channels: 4,
        background: { r: 0, g: 0, b: 0, alpha: 0 },
      },
    })
      .composite([{ input: bigImage, top, left }])
      .png()
      .toFile(join(outputFolder, "1920x1080.png"));

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

image

Thank you very much in advance :)

penchochris commented 1 year ago

OK... nvm, I found a workaround, here's the solution:

// create a "canvas" big enought to fit the "very big img" and the 1080p img
 const canvas =
    await sharp({
      create: {
        width: 4000,
        height: 4000,
        channels: 4,
        background: { r: 0, g: 0, b: 0, alpha: 0 },
      },
    })

      .composite([
        composited1080pImage, // this one needs to be "toBuffer()" and top: 0, left: 0
        compositedVeryBigImage // toBuffer() aswell
      ])
      .png()
      .toBuffer();

     await sharp(canvas) // then you extract the part you need as 1080p :)
      .extract({
        left: 0,
        top: 0,
        width: 1920,
        height: 1080,
      })
      .png()
      .toFile(join(outputFolder, "1920x1080.png"));
lovell commented 1 year ago

Yes, you'll need to clip/crop the images to composite.

https://sharp.pixelplumbing.com/api-composite#composite

The images to composite must be the same size or smaller than the processed image.

lovell commented 1 year ago

I hope this information helped. Please feel free to re-open with more details if further assistance is required.