0

这些是我用于向图像添加水印的代码:

    const ORIGINAL_IMAGE = "https://example/sample_image;
    const LOGO = fs.readFileSync('gangle.png');
    const LOGO_MARGIN_PERCENTAGE = 5;

    let [image, logo] = await Promise.all([
      Jimp.read(ORIGINAL_IMAGE),
      Jimp.read(LOGO)
    ]);

    logo.resize(image.bitmap.width, Jimp.AUTO);

    const xMargin = (image.bitmap.width * LOGO_MARGIN_PERCENTAGE) / 100;
    const yMargin = (image.bitmap.width * LOGO_MARGIN_PERCENTAGE) / 100;

    const X = image.bitmap.width - logo.bitmap.width - xMargin;
    const Y = image.bitmap.height - logo.bitmap.height - yMargin;

    image.composite(logo, X, Y, [
      {
        mode: Jimp.BLEND_SCREEN,
        opacitySource: 0.1,
        opacityDest: 1
      }
    ]);

    image.write('animatedimg.gif')

但它仅适用于文件类型为 png/jpg/jpeg 的图像。它不适用于 gif 图像。

它将生成一个文件“animatedimg.gif”,但该文件不会加载到任何图像查看器或浏览器。

如果我尝试在 mac 中打开该文件,弹出窗口将显示消息:“文件“animatedimg.gif”无法打开,因为它是空的。”

有没有办法在 jimp 中做到这一点?或者还有其他 npm 包吗?谢谢你。

4

2 回答 2

2

令人困惑的是,Jimp 只处理单帧GIF,而不是大多数人认为的多帧动画 GIF。所以你需要使用gifwrap

从那里您可以遍历多帧 GIF 中的每一帧。每个帧都是一个GifFrame,可以来回转换为 Jimp 实例(请参阅文档中的Leveraging Jimp)。您可以将水印添加到与GifFrame. 像这样的东西:

async function getGifFramesWithWatermarks(gifPath) {
  const readGif = await GifUtil.read(gifPath);
  const promises = readGif.frames.map(getGifFrameWithWatermark);
  const gifFramesWithWatermarks = await Promise.all(promises);

  return gifFramesWithWatermarks;
}

async function getGifFrameWithWatermark(gifFrame) {
  const jimpImage = GifUtil.copyAsJimp(Jimp, gifFrame);

  addWatermark(jimpImage); // function you will write

  return new GifFrame(jimpImage.bitmap, {
    disposalMethod: gifFrame.disposalMethod, // not documented by gifwrap but it's in the source
    delayCentisecs: gifFrame.delayCentisecs, // you'll probably want this
  });
}

const gifFramesWithWatermarks = await getGifFramesWithWatermark(GIF_PATH);
await GifUtil.write(WRITE_PATH, gifFramesWithWatermarks);
于 2020-12-22T22:06:01.563 回答
2

更新 我写了这个 npm 库,你可以用它在 gif 上写文本。它仍然有一些错误:https ://www.npmjs.com/package/text-on-gif

这对我有用

const Jimp = require("jimp");
const { GifUtil,GifFrame,BitmapImage} = require('gifwrap');
var frames = [];

Jimp.loadFont(Jimp.FONT_SANS_32_WHITE).then(async function(font){
    await GifUtil.read("gif.gif").then(inputGif => {
        inputGif.frames.forEach(function(frame){
            jimpCopied = GifUtil.copyAsJimp(Jimp, frame);
            jimpCopied.print(font,0,0,"sanidhya");
            const GifCopied = new GifFrame(new BitmapImage(jimpCopied.bitmap,{
                disposalMethod: frame.disposalMethod,
                delayCentisecs: frame.delayCentisecs,
            }));
        frames.push(GifCopied);   
        });
    });
    GifUtil.quantizeDekker(frames);
    GifUtil.write("nyahhaha.gif",frames);
});

笔记

仅当您的 Frame 使用超过 256 个颜色索引时才需要 qunatize*() 函数

于 2021-01-21T08:14:29.713 回答