sharp icon indicating copy to clipboard operation
sharp copied to clipboard

Enhancement: allow pageHeight to be set for raw input and when creating images

Open everskies opened this issue 3 years ago • 4 comments

Is there currently a way to merge multiple images into a single animation file using Sharp/Libvips?

I've tried using raw buffer data that contains 10 frames, however calling metadata() shows that there is only a single page

  const outputBuffer = Buffer.concat(frames); // 10 different frames merged into a single buffer

  const animatedImage = sharp(outputBuffer, {
      raw: {
          width: canvasSize.x,
          height: canvasSize.y,
          channels: 4,
      },
      animated: true,
      pages: 10,
  });
  
  console.log(await animatedImage.metadata());
console.log:
{
  format: 'raw',
  size: 3005600,
  width: 221,
  height: 340,
  space: 'srgb',
  channels: 4,
  depth: 'uchar',
  isProgressive: false,
  hasProfile: false,
  hasAlpha: true
}

Saving to WebP also results in a single (non animated) frame

  animatedImage.webp({
    delay: frames.map(() => 100),
    lossless: true,
  }).toBuffer();

everskies avatar May 21 '22 17:05 everskies

Please see future possible enhancement #1580

lovell avatar Jun 06 '22 12:06 lovell

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

lovell avatar Jun 22 '22 15:06 lovell

Just in case, has anything changed here @lovell? I'm trying to create an animated webp file from raw pixel data. sharp(array, { raw: { width, height, channels }, animated: true }).webp().toFile(...) does not work, only one frame is created :/ My current solution is to export single frames as images and concat them with ffmeg. This works, but it would be nice if it could be done just using sharp

nikolasdas avatar Mar 12 '23 11:03 nikolasdas

I'm re-opening as this has come up again in #4092 and I can see there's a group of requests here that differ slightly from #1580 in that they relate only to raw, uncompressed pixel data input.

This proposed API might allow enough to be able to achieve this.

// PROPOSED API, NOT YET AVAILABLE
await sharp(rawInput, {
  raw: {
    width: 8,
    height: 24,
    pageHeight: 8,
    channels: 4
  }
})...

This might also be relevant when creating new images:

// PROPOSED API, NOT YET AVAILABLE
await sharp({
  create: {
    width: 8,
    height: 24,
    pageHeight: 8,
    channels: 4,
    background: 'green'
  }
})...

The use of pageHeight as a property name is to avoid possible confusion with the existing pages property that determines how many pages of a multi-page image are to be opened.

There would need to be some height % pageHeight === 0 validation too.

lovell avatar Apr 30 '24 08:04 lovell