当前位置: 首页 > 工具软件 > Gifshot > 使用案例 >

gifshot.js合成GIF

滕英奕
2023-12-01

gifshot.js:可以从媒体流、视频或图像创建动画 GIF 的 JavaScript 库。

https://github.com/yahoo/gifshot

经测试:

text配置项:
生成的GIF每一帧所覆盖的文本;

images配置项(数组):
首个设置的图片会一直显示;
如设置text,则优先级最高,当前(帧)图片覆盖文本替换text配置项全局文本;

demo:多张图片合成GIF图片;VIDEO生成的GIF;
demo资源下载

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>gifshot.js合成GIF</title>
<style type="text/css">
  body{ background-color: #ddd;}
</style>
</head>
<body>
  
  
  <div class="">
    <p>gifshot.js:可以从媒体流、视频或图像创建动画 GIF 的 JavaScript 库。</p>
    <p><a href="https://github.com/yahoo/gifshot">https://github.com/yahoo/gifshot</a></p>
    <p>经测试:</p>
    <p>text配置项:<br>生成的GIF每一帧所覆盖的文本;</p>
    <p>images配置项(数组):<br>首个设置的图片会一直显示;<br>如设置text,则优先级最高,当前(帧)图片覆盖文本替换text配置项全局文本;</p>
    <p>demo:多张图片合成GIF图片;VIDEO生成的GIF;</p>
  </div>
  
  <div style="text-align: center;display: flex; justify-content: center; align-items: flex-start;">
    <div id="img1" style="width: 30%;">
      <p>所有图片PNG生成的GIF <span></span></p>
    </div>
    <div id="img2" style="width: 30%;">
      <p>所有图片JPG生成的GIF <span></span></p>
    </div>
    <div id="img3" style="width: 30%;">
      <p>VIDEO生成的GIF <span></span></p>
    </div>
  </div>
  
  <!-- <script src="gifshot.js"></script> -->
  <script src="gifshot.min.js"></script>
  
  
  <!-- 所有图片PNG生成的GIF -->
  <script type="text/javascript">
    gifshot.createGIF({
      // 图片的宽度
      'gifWidth' : 300,
      // 图片的高度
      'gifHeight' : 300,
      // 如果使用此选项,则将使用这些图片创建 GIF 
      // 注意:确保这些图像资源启用了 CORS 以防止任何跨域 JavaScript 错误
      // 注意:您还可以传递页面上现有图像元素的 NodeList 
      'images' : [
        { src:'img/png/base.png',text:'我是第 1 张图片(所有图片PNG)'},
        { src:'img/png/1.png',text:'第 2 张'},
        { src:'img/png/2.png',text:'第 3 张'},
        { src:'img/png/3.png',text:'第 4 张'},
        { src:'img/png/4.png',text:'第 5 张'},
        { src:'img/png/5.png',text:'第 6 张'},
        { src:'img/png/6.png',text:'第 7 张'},
        { src:'img/png/7.png',text:'第 8 张'},
        { src:'img/png/8.png',text:'第 9 张'},
      ],
      // 如果使用此选项,则将使用适当的视频创建 gif
      // 您想从中创建动画 GIF 的 HTML5 视频
      // 注意:已检查浏览器对某些视频编解码器的支持,并选择了适当的视频
      // 注意:您还可以传递页面上现有视频元素的 NodeList 
      // 例如 'video': ['example.mp4', 'example.ogv'], 
      'video' : null,
      // 你可以传递一个现有的 video 元素用于网络摄像头 GIF 创建过程,
      // 和这个视频元素不会被隐藏(与 keepCameraOn 选项一起使用时很有用)
      // 专业提示:将视频元素的高度和宽度设置为与您未来的 GIF 相同的值
      // 另一个专业提示:如果您使用此选项,视频不会被暂停,对象 url 不会被撤销,并且
      // 视频不会从 DOM 中删除。您需要自己处理。
      'webcamVideoElement' : null,
      // 您是否希望在创建 GIF 后用户的相机保持开启
      // 注意:cameraStream Media 对象在 createGIF() 回调函数中传回给您
      'keepCameraOn' : false,
      // 需要一个 cameraStream 媒体对象
      // 注意:如果您不使用 SSL 
      // 传递现有的相机流将允许您创建另一个 GIF 和/或快照,而无需请求用户再次访问相机的权限
      'cameraStream':null,
      // 将应用于图像的 CSS 过滤器(例如 blur(5px))
      'filter' : '',
      // 每帧捕获之间等待的时间(以秒为单位)
      'interval' : 0.1,
      //开始捕获 GIF 的时间(以秒为单位)(仅适用于 HTML5 视频)
      'offset' : null,
      // 用于创建动画 GIF 的帧数
      // 注意:每帧每 100 毫秒捕获一次现有图像的视频和每毫秒
      'numFrames' : 10, //视频中捕获的生成GIF的帧数
      // 每帧停留的时间 (10 = 1s) 
      'frameDuration' : 1,
      // 覆盖动画 GIF的文本
      'text' : '生成的GIF每一帧所覆盖的文本',
      // 覆盖动画 GIF 的文本的字体粗细
      'fontWeight' : 'normal',
      // 覆盖动画 GIF 的文本的字体大小
      'fontSize' : '16px',
      // 覆盖动画 GIF 的文本的最小字体大小
      // 注意:该选项仅在正在应用的文本被截断时应用
      'minFontSize' : '10px',
      // 是否动画 GIF 文本是否会调整大小以适应 GIF 容器
      'resizeFont' : false,
      // 覆盖动画 GIF 的文本的字体系列
      'fontFamily' : 'sans-serif',
      // 覆盖动画 GIF 的文本的字体颜色
      // 'fontColor' : '#dd0000',
      'fontColor' : 'green',
      // 水平文本覆盖动画 GIF的文本对齐方式
      'textAlign' : 'center',
      // 覆盖动画 GIF 的文本的垂直文本对齐方式
      'textBaseline' : 'bottom',
      // 文本的 X(水平)坐标涵盖动画 GIF(仅在默认 textAlign 和 textBaseline 选项不适合您时使用)
      'textXCoordinate':null, 
      // 覆盖动画 GIF 的文本的 Y(垂直)坐标(仅在默认的 textAlign 和 textBaseline 选项不适合您时使用)
      'textYCoordinate' : null,
      // 提供当前进度的回调函数当前图像的
      'progressCallback' : function (captureProgress){
        // console.log(captureProgress);
        document.getElementById('img1').getElementsByTagName('span')[0].innerHTML = parseInt(captureProgress * 100) + '%';
      },
      // 当前图像完成时调用的回调函数
      'completeCallback' : function (){
        console.log('当前图像完成时调用的回调函数')
      },
      // 创建调色板时要跳过多少像素。默认值为 10。越少越好,但更慢。
      // 注意:通过调整采样间隔,既可以慢慢产生极高质量的图像,也可以在合理的时间内产生好的图像。
      // sampleInterval 为 1,整个图像用于学习阶段,而间隔为 10,
      // 1/10 像素的伪随机子集用于学习阶段。10 的采样因子给出了
      // 显着的加速,但质量损失很小。
      'sampleInterval' : 10,
      // 使用多少网络工作者来处理动画 GIF 帧。默认为 2。
      'numWorkers' : 2,
      // 您是否希望从创建的 GIF 中保存所有画布图像二进制数据
      // 注意:当您想重新使用 GIF 将文本添加到以后的
      'saveRenderingContexts':false,
      // 需要一个画布图像数据数组
      // 注意:如果您将 saveRenderingContexts 选项设置为 true,然后在 createGIF 回调函数'savedRenderingContexts'中获得
      "savedRenderingContexts": [],
      // 当请求使用现有图像或视频时,我们在请求上设置 CORS 属性。
      // 选项是 'Anonymous'、'use-credentials' 或虚假值(如 '')以不设置 CORS 属性。
      'showFrameText':true,
      // 如果图像数组提供了特定于框架的文本,则可以通过将此选项设置为“false”来强制不显示特定于框架的文本。
      'crossOrigin' : 'Anonymous',
      // 水印图像 如果这里给出了图像,它将被标记在 GIF 帧的顶部
      "waterMark" : null,
      // 水印图像 的高度
      "waterMarkHeight" : null,
      // 水印图像 的宽度
      "waterMarkWidth" : null,
      // 水印图像的 X(水平)坐标
      "waterMarkXCoordinate" : 1,
      //水印图像的Y(垂直)坐标
      "waterMarkYCoordinate" : 1
    },function(obj) {
      if(!obj.error) {
        var image = obj.image,
        animatedImage = document.createElement('img');
        animatedImage.src = image;
        // document.body.appendChild(animatedImage);
        document.getElementById('img1').appendChild(animatedImage);
      }
    });
  </script>
  
  
  <!-- 所有图片JPG生成的GIF -->
  <script type="text/javascript">
    gifshot.createGIF({
      // 图片的宽度
      'gifWidth' : 300,
      // 图片的高度
      'gifHeight' : 300,
      // 如果使用此选项,则将使用这些图片创建 GIF 
      // 注意:确保这些图像资源启用了 CORS 以防止任何跨域 JavaScript 错误
      // 注意:您还可以传递页面上现有图像元素的 NodeList 
      'images' : [
        { src:'img/jpg/base.jpg',text:'我是第 1 张图片(所有图片JPG)'},
        { src:'img/jpg/1.jpg',text:'第 2 张'},
        { src:'img/jpg/2.jpg',text:'第 3 张'},
        { src:'img/jpg/3.jpg',text:'第 4 张'},
        { src:'img/jpg/4.jpg',text:'第 5 张'},
        { src:'img/jpg/5.jpg',text:'第 6 张'},
        { src:'img/jpg/6.jpg',text:'第 7 张'},
        { src:'img/jpg/7.jpg',text:'第 8 张'},
        { src:'img/jpg/8.jpg',text:'第 9 张'},
      ],
      // 如果使用此选项,则将使用适当的视频创建 gif
      // 您想从中创建动画 GIF 的 HTML5 视频
      // 注意:已检查浏览器对某些视频编解码器的支持,并选择了适当的视频
      // 注意:您还可以传递页面上现有视频元素的 NodeList 
      // 例如 'video': ['example.mp4', 'example.ogv'], 
      'video' : null,
      // 你可以传递一个现有的 video 元素用于网络摄像头 GIF 创建过程,
      // 和这个视频元素不会被隐藏(与 keepCameraOn 选项一起使用时很有用)
      // 专业提示:将视频元素的高度和宽度设置为与您未来的 GIF 相同的值
      // 另一个专业提示:如果您使用此选项,视频不会被暂停,对象 url 不会被撤销,并且
      // 视频不会从 DOM 中删除。您需要自己处理。
      'webcamVideoElement' : null,
      // 您是否希望在创建 GIF 后用户的相机保持开启
      // 注意:cameraStream Media 对象在 createGIF() 回调函数中传回给您
      'keepCameraOn' : false,
      // 需要一个 cameraStream 媒体对象
      // 注意:如果您不使用 SSL 
      // 传递现有的相机流将允许您创建另一个 GIF 和/或快照,而无需请求用户再次访问相机的权限
      'cameraStream':null,
      // 将应用于图像的 CSS 过滤器(例如 blur(5px))
      'filter' : '',
      // 每帧捕获之间等待的时间(以秒为单位)
      'interval' : 0.1,
      //开始捕获 GIF 的时间(以秒为单位)(仅适用于 HTML5 视频)
      'offset' : null,
      // 用于创建动画 GIF 的帧数
      // 注意:每帧每 100 毫秒捕获一次现有图像的视频和每毫秒
      'numFrames' : 10, //视频中捕获的生成GIF的帧数
      // 每帧停留的时间 (10 = 1s) 
      'frameDuration' : 1,
      // 覆盖动画 GIF的文本
      'text' : '生成的GIF每一帧所覆盖的文本',
      // 覆盖动画 GIF 的文本的字体粗细
      'fontWeight' : 'normal',
      // 覆盖动画 GIF 的文本的字体大小
      'fontSize' : '16px',
      // 覆盖动画 GIF 的文本的最小字体大小
      // 注意:该选项仅在正在应用的文本被截断时应用
      'minFontSize' : '10px',
      // 是否动画 GIF 文本是否会调整大小以适应 GIF 容器
      'resizeFont' : false,
      // 覆盖动画 GIF 的文本的字体系列
      'fontFamily' : 'sans-serif',
      // 覆盖动画 GIF 的文本的字体颜色
      // 'fontColor' : '#dd0000',
      'fontColor' : 'green',
      // 水平文本覆盖动画 GIF的文本对齐方式
      'textAlign' : 'center',
      // 覆盖动画 GIF 的文本的垂直文本对齐方式
      'textBaseline' : 'bottom',
      // 文本的 X(水平)坐标涵盖动画 GIF(仅在默认 textAlign 和 textBaseline 选项不适合您时使用)
      'textXCoordinate':null, 
      // 覆盖动画 GIF 的文本的 Y(垂直)坐标(仅在默认的 textAlign 和 textBaseline 选项不适合您时使用)
      'textYCoordinate' : null,
      // 提供当前进度的回调函数当前图像的
      'progressCallback' : function (captureProgress){
        // console.log(captureProgress);
        document.getElementById('img2').getElementsByTagName('span')[0].innerHTML = parseInt(captureProgress * 100) + '%';
      },
      // 当前图像完成时调用的回调函数
      'completeCallback' : function (){
        console.log('当前图像完成时调用的回调函数')
      },
      // 创建调色板时要跳过多少像素。默认值为 10。越少越好,但更慢。
      // 注意:通过调整采样间隔,既可以慢慢产生极高质量的图像,也可以在合理的时间内产生好的图像。
      // sampleInterval 为 1,整个图像用于学习阶段,而间隔为 10,
      // 1/10 像素的伪随机子集用于学习阶段。10 的采样因子给出了
      // 显着的加速,但质量损失很小。
      'sampleInterval' : 10,
      // 使用多少网络工作者来处理动画 GIF 帧。默认为 2。
      'numWorkers' : 2,
      // 您是否希望从创建的 GIF 中保存所有画布图像二进制数据
      // 注意:当您想重新使用 GIF 将文本添加到以后的
      'saveRenderingContexts':false,
      // 需要一个画布图像数据数组
      // 注意:如果您将 saveRenderingContexts 选项设置为 true,然后在 createGIF 回调函数'savedRenderingContexts'中获得
      "savedRenderingContexts": [],
      // 当请求使用现有图像或视频时,我们在请求上设置 CORS 属性。
      // 选项是 'Anonymous'、'use-credentials' 或虚假值(如 '')以不设置 CORS 属性。
      'showFrameText':true,
      // 如果图像数组提供了特定于框架的文本,则可以通过将此选项设置为“false”来强制不显示特定于框架的文本。
      'crossOrigin' : 'Anonymous',
      // 水印图像 如果这里给出了图像,它将被标记在 GIF 帧的顶部
      "waterMark" : null,
      // 水印图像 的高度
      "waterMarkHeight" : null,
      // 水印图像 的宽度
      "waterMarkWidth" : null,
      // 水印图像的 X(水平)坐标
      "waterMarkXCoordinate" : 1,
      //水印图像的Y(垂直)坐标
      "waterMarkYCoordinate" : 1
    },function(obj) {
      if(!obj.error) {
        var image = obj.image,
        animatedImage = document.createElement('img');
        animatedImage.src = image;
        // document.body.appendChild(animatedImage);
        document.getElementById('img2').appendChild(animatedImage);
      }
    });
  </script>
  
  
  <!-- VIDEO生成的GIF -->
  <script type="text/javascript">
    gifshot.createGIF({
      // 图片的宽度
      'gifWidth' : 300,
      // 图片的高度
      'gifHeight' : 300,
      // 如果使用此选项,则将使用这些图片创建 GIF 
      // 注意:确保这些图像资源启用了 CORS 以防止任何跨域 JavaScript 错误
      // 注意:您还可以传递页面上现有图像元素的 NodeList 
      // 'images' : ,
      // 如果使用此选项,则将使用适当的视频创建 gif
      // 您想从中创建动画 GIF 的 HTML5 视频
      // 注意:已检查浏览器对某些视频编解码器的支持,并选择了适当的视频
      // 注意:您还可以传递页面上现有视频元素的 NodeList 
      // 例如 'video': ['example.mp4', 'example.ogv'], 
      'video' : ['img/video.mp4'],
      // 你可以传递一个现有的 video 元素用于网络摄像头 GIF 创建过程,
      // 和这个视频元素不会被隐藏(与 keepCameraOn 选项一起使用时很有用)
      // 专业提示:将视频元素的高度和宽度设置为与您未来的 GIF 相同的值
      // 另一个专业提示:如果您使用此选项,视频不会被暂停,对象 url 不会被撤销,并且
      // 视频不会从 DOM 中删除。您需要自己处理。
      'webcamVideoElement' : null,
      // 您是否希望在创建 GIF 后用户的相机保持开启
      // 注意:cameraStream Media 对象在 createGIF() 回调函数中传回给您
      'keepCameraOn' : false,
      // 需要一个 cameraStream 媒体对象
      // 注意:如果您不使用 SSL 
      // 传递现有的相机流将允许您创建另一个 GIF 和/或快照,而无需请求用户再次访问相机的权限
      'cameraStream':null,
      // 将应用于图像的 CSS 过滤器(例如 blur(5px))
      'filter' : '',
      // 每帧捕获之间等待的时间(以秒为单位)
      'interval' : 0.1,
      //开始捕获 GIF 的时间(以秒为单位)(仅适用于 HTML5 视频)
      'offset' : null,
      // 用于创建动画 GIF 的帧数
      // 注意:每帧每 100 毫秒捕获一次现有图像的视频和每毫秒
      'numFrames' : 50, //视频中捕获的生成GIF的帧数
      // 每帧停留的时间 (10 = 1s) 
      'frameDuration' : 1,
      // 覆盖动画 GIF的文本
      'text' : '生成的GIF每一帧所覆盖的文本(VIDEO生成的GIF)',
      // 覆盖动画 GIF 的文本的字体粗细
      'fontWeight' : 'normal',
      // 覆盖动画 GIF 的文本的字体大小
      'fontSize' : '12px',
      // 覆盖动画 GIF 的文本的最小字体大小
      // 注意:该选项仅在正在应用的文本被截断时应用
      'minFontSize' : '10px',
      // 是否动画 GIF 文本是否会调整大小以适应 GIF 容器
      'resizeFont' : false,
      // 覆盖动画 GIF 的文本的字体系列
      'fontFamily' : 'sans-serif',
      // 覆盖动画 GIF 的文本的字体颜色
      // 'fontColor' : '#dd0000',
      'fontColor' : 'white',
      // 水平文本覆盖动画 GIF的文本对齐方式
      'textAlign' : 'center',
      // 覆盖动画 GIF 的文本的垂直文本对齐方式
      'textBaseline' : 'bottom',
      // 文本的 X(水平)坐标涵盖动画 GIF(仅在默认 textAlign 和 textBaseline 选项不适合您时使用)
      'textXCoordinate':null, 
      // 覆盖动画 GIF 的文本的 Y(垂直)坐标(仅在默认的 textAlign 和 textBaseline 选项不适合您时使用)
      'textYCoordinate' : null,
      // 提供当前进度的回调函数当前图像的
      'progressCallback' : function (captureProgress){
        // console.log(captureProgress);
        document.getElementById('img3').getElementsByTagName('span')[0].innerHTML = parseInt(captureProgress * 100) + '%';
      },
      // 当前图像完成时调用的回调函数
      'completeCallback' : function (){
        console.log('当前图像完成时调用的回调函数')
      },
      // 创建调色板时要跳过多少像素。默认值为 10。越少越好,但更慢。
      // 注意:通过调整采样间隔,既可以慢慢产生极高质量的图像,也可以在合理的时间内产生好的图像。
      // sampleInterval 为 1,整个图像用于学习阶段,而间隔为 10,
      // 1/10 像素的伪随机子集用于学习阶段。10 的采样因子给出了
      // 显着的加速,但质量损失很小。
      'sampleInterval' : 10,
      // 使用多少网络工作者来处理动画 GIF 帧。默认为 2。
      'numWorkers' : 2,
      // 您是否希望从创建的 GIF 中保存所有画布图像二进制数据
      // 注意:当您想重新使用 GIF 将文本添加到以后的
      'saveRenderingContexts':false,
      // 需要一个画布图像数据数组
      // 注意:如果您将 saveRenderingContexts 选项设置为 true,然后在 createGIF 回调函数'savedRenderingContexts'中获得
      "savedRenderingContexts": [],
      // 当请求使用现有图像或视频时,我们在请求上设置 CORS 属性。
      // 选项是 'Anonymous'、'use-credentials' 或虚假值(如 '')以不设置 CORS 属性。
      'showFrameText':true,
      // 如果图像数组提供了特定于框架的文本,则可以通过将此选项设置为“false”来强制不显示特定于框架的文本。
      'crossOrigin' : 'Anonymous',
      // 水印图像 如果这里给出了图像,它将被标记在 GIF 帧的顶部
      "waterMark" : null,
      // 水印图像 的高度
      "waterMarkHeight" : null,
      // 水印图像 的宽度
      "waterMarkWidth" : null,
      // 水印图像的 X(水平)坐标
      "waterMarkXCoordinate" : 1,
      //水印图像的Y(垂直)坐标
      "waterMarkYCoordinate" : 1
    },function(obj) {
      if(!obj.error) {
        var image = obj.image,
        animatedImage = document.createElement('img');
        animatedImage.src = image;
        // document.body.appendChild(animatedImage);
        document.getElementById('img3').appendChild(animatedImage);
      }
    });
  </script>
    

</body>
</html>

 类似资料: