GIF(重新)压缩概念的Javascript证明

GIF(重新)压缩概念的Javascript证明,javascript,compression,gif,bzip2,Javascript,Compression,Gif,Bzip2,我的程序可以用来进一步压缩已经压缩的文件格式,如GIF、PNG、PDF、ZIP等。粗略地说,它是通过解压缩压缩流、重新压缩它们并存储预期压缩流和实际压缩流之间的差异来实现的。例如,Wikipedia中的内容从1429KB压缩到755KB。该过程是无损的,因此可以恢复原始GIF文件 GIF文件格式的算法可以相对容易地隔离和实现,因此我考虑用JavaScript实现概念验证。这将导致web服务器发送GIF文件的压缩版本(.pcf end),本质上是 GIF图像内容)和客户端解压缩数据,重新压缩为GI

我的程序可以用来进一步压缩已经压缩的文件格式,如GIF、PNG、PDF、ZIP等。粗略地说,它是通过解压缩压缩流、重新压缩它们并存储预期压缩流和实际压缩流之间的差异来实现的。例如,Wikipedia中的内容从1429KB压缩到755KB。该过程是无损的,因此可以恢复原始GIF文件

GIF文件格式的算法可以相对容易地隔离和实现,因此我考虑用JavaScript实现概念验证。这将导致web服务器发送GIF文件的压缩版本(.pcf end),本质上是 GIF图像内容)和客户端解压缩数据,重新压缩为GIF并显示。必须做以下几件事:

  • 网站作者必须使用标准版本的Precomp压缩他的GIF文件,并将这些文件(而不是GIF文件)与JavaScript一起提供给客户端重新压缩
  • 客户机将解压缩bzip2压缩文件,这可以使用
  • 客户端会将图像内容重新压缩到原始GIF文件中
这个过程是带宽与客户端CPU使用率的权衡

现在我的问题是:


  • 加载不同文件并将其“转换”为GIF的过程中是否存在任何一般性问题
  • 在客户端完成之前,您建议显示什么(图像占位符)
  • 我必须做些什么来确保.pcf文件被缓存?如果没有缓存,节省的带宽是无用的
  • 如果JavaScript被停用,是否有办法显示原始GIF,但如果JavaScript被激活,则避免加载GIF
  • 我可以给用户一种配置行为的方法吗?例如,在移动设备上,一些可能会避免带宽,但另一些可能希望减少CPU使用
  • 是否可以按设想显示交错GIF(从粗略版本到最终图像)?这需要在重新压缩的不同阶段多次更新图像内容

    • 让我们从回答您的具体问题开始。下面的代码示例


      问答


    • 加载不同文件并将其“转换”为GIF的过程中是否存在任何一般性问题
    • 主要问题是复杂性。您实际上是在编写一个浏览器插件,就像JPEG2000的插件一样

      如果您正在编写真正的浏览器插件,那么每个主要浏览器的做法都不同,并且偶尔会更改插件格式,因此您必须积极维护它们

      如果您正在编写JS库,那么编写和维护它将更容易,但它将不受特权限制,并且会受到以下限制:

    • 在客户端完成之前,您建议显示什么(图像占位符)
    • 取决于你的格式能提供什么。 如果及早对图像尺寸和小缩略图进行编码,则可以很早地显示准确的占位符

      毕竟,这是你的格式

    • 我必须做些什么来确保.pcf文件被缓存?如果没有缓存,节省的带宽是无用的
    • 与其他文件没有什么不同

      在服务器端配置,它们将被缓存。 也可以使用

    • 如果JavaScript被停用,是否有办法显示原始GIF,但如果JavaScript被激活,则避免加载GIF
    • 这很棘手。禁用JavaScript时,只能使用属性,不能使用属性

      这意味着您无法在某处创建指向.pcf文件的图像,并在JS不可用时要求浏览器重写src属性

      我认为支持无JS的最佳解决方案是使用
      document.write
      ,使用
      noscript
      作为后援输出图像:

      <noscript>
        <img src=demo.gif width=90>
      </noscript><script>
        loadPcf("demo.pcf","width=90")
      </script>
      
      
      loadPcf(“demo.pcf”,“宽度=90”)
      

      (某些库或框架可能会让您考虑<代码> <代码>。 这对您不起作用,因为在脚本启动之前,浏览器会显示“demo.gif”,从而导致额外的数据传输。)

      或者,浏览器插件不受“禁用JS”设置的影响,因此,如果您制作插件,则无需担心

    • 我可以给用户一种配置行为的方法吗?例如,在移动设备上,一些可能会避免带宽,但另一些可能希望减少CPU使用
    • 也许吧。您可以编写用户界面代码并将首选项存储在cookie或localStorage中。 然后,您可以检测首选项并在服务器代码(如果是cookie)或客户端代码中切换逻辑

      如果您使用的是插件,那么所有浏览器都提供了可靠的首选项机制。 问题是,同样,每个浏览器都有不同的做法

    • 是否可以按设想显示交错GIF(从粗略版本到最终图像)?这需要在重新压缩的不同阶段多次更新图像内容
    • 如果您将部分图像交给浏览器,他们可能会认为该图像已损坏并拒绝显示。 在这种情况下,为了安全起见,您必须实现自己的GIF解码器和编码器,以便可以将完整的占位符图像交给浏览器

    • (新增)我可以解码从其他站点加载的图像吗
    • 我还必须重复警告,非插件JS图像解码无法使用。 这意味着,所有.pcf文件必须与使用它的站点位于同一服务器、同一端口和同一协议上

      例如,您不能共享多个站点的图像或进行类似的优化


      代码示例

      下面是一个创建
      
      傻瓜加载PCF(“a.gif”,“宽度=90”)条
      
      如果您不需要
      兼容性(以及
        <!DOCTYPE html><html><head><meta charset="UTF-8"><script>
        function loadPcf( file, attr ) {
           var atr = attr || '', id = loadPcf.autoid = 1 + ~~loadPcf.autoid;
           document.write( '<img id=pcf'+id+' ' + atr + ' />' );
           var xhr = new XMLHttpRequest();
           xhr.responseType = 'arraybuffer'; // IE 10+ only, sorry.
           xhr.onload = function() { // I am loading gif for demo, you can load anything.
              var data = xhr.response, img = document.querySelector( '#pcf' + id );
              if ( ! img || ! data instanceof ArrayBuffer ) return;
              var buf = new DataView( data ), head = buf.getUint32(0), width = buf.getUint16(6,1);
              if ( head !== 1195984440 ) return console.log( 'Not a GIF: ' + file ); // 'GIF8' = 1195984440
              // Modify data, image width in this case, and push it to the <img> as gif.
              buf.setInt16( 6, ~~(width/2), 1 );
              img.src = URL.createObjectURL( new Blob( [ buf.buffer ], { type: "image/gif" } ) );
           };
           xhr.open( 'GET', file );
           xhr.send();
        }
        </script>
        <h1>Foo<noscript><img src=a.gif width=90></noscript><script>loadPcf("a.gif","width=90")</script>Bar</h1>