似乎无论您在网上如何寻找将静态背景图像(例如 png 或 jpeg)与 gif 合成的方法,都没有完整的解决方案。 Sharp 似乎不支持在静止背景上叠加 gif 图像,或者至少在大多数情况下不支持。如何通过叠加将静态背景图像与 gif 合成为新的 gif?
谢谢
这个问题的答案非常微妙,因为有许多不同的缺点和子任务必须解决。
在某些情况下,您需要调整图像大小以允许 gif 整齐地覆盖 gif。
通过在静止背景上叠加 gif 来创建动画 gif 的过程需要几个步骤。
您需要确保在导入 gif 时,已将 animated 选项设置为 true (因为默认情况下为 false)。
首先确保 gif 和输入图像的大小兼容(根据 docs,叠加层必须与输入图像大小相同或小于输入图像)。因此,应考虑任何调整大小、裁剪或定位。您需要对图像进行处理,以便它们具有相同的尺寸(如果还没有),或者在合成时您必须定义您的位置。
其次,您必须扩展静态输入图像,以便它创建一个胶片卷(或者有些人可能称之为卫生卷)。垂直重复静态图像。
最后,您可以将扩展的静态图像和 gif 合成在一起,将其转换为 gif 格式并另存为 .gif 文件。
async function overlayGif(background, gifOverlay) { //takes two input paths.
const overlay = await sharp(gifOverlay, {animated: true}); //make sure animated is true.
const metadata = await overlay.metadata(); //We'll use the gif metadata to normalize the background.
const backgroundImg = await sharp(background).resize(metadata.width, metadata.height/metadata.pages); //We are resizing here to normalize background with gif.
const imgRoll = backgroundImg.extend({bottom: metadata.height/metadata.pages*(metadata.pages-1), extendWith: 'repeat'}); //Must extend to repeat how ever many pages (frames) are in the gif.
const result = await imgRoll.composite([
{ input: await overlay.toBuffer(), gravity: 'center', animated: true}
]).gif(
{progressive: metadata.isProgressive, delay: metadata.delay, loop: metadata.loop}
//Just copying the metadata from the gif to the output format (not sure this is necessary).
);
const resInfo = await result.toFile("output.gif"); //Write the result to a gif file.
return result;
}
如果您使用上面的代码,您会注意到合成元数据结果存在一些问题...主要限制是生成的元数据格式不是 gif,而是背景图像的任何格式(png、jpeg 等)。 ..所以你不能真正使用它的任何元数据功能(即使你使用force属性强制格式为gif,元数据仍然保留背景图像格式),尽管它看起来确实是一个gif .