【问题标题】:Automated optimization of PNGs inside CSS files (data URIs) using ZopfliPNG使用 ZopfliPNG 自动优化 CSS 文件(数据 URI)中的 PNG
【发布时间】:2016-07-13 13:53:12
【问题描述】:

我有一些带有内联图像(base64 编码数据 URI [AKA 数据 URL])的 CSS 和 LESS 文件,其中一些是 PNG。我希望使用 ZopfliPNG 以自动方式对这些 PNG 进行编码。

可悲的是,ZopfliPNG 似乎只能处理文件而不是例如。使用标准输入/标准输出(诸如“Support piping input”之类的错误跟踪器条目仍处于打开状态),这使事情变得更加复杂。

【问题讨论】:

    标签: css png data-uri


    【解决方案1】:

    Leanify(我写的)支持优化 CSS 文件中的数据 URI 图像。它在内部对 PNG 文件使用 ZopfliPNG。

    与您的 python 脚本相比,它有一些优势:

    1. 还支持JPEG、ICO、SVG等其他图片格式。

    2. 不需要临时文件,一切都在内存中完成。

    3. Data URI 搜索具有更好的兼容性。对于 CSS 文件,url(data:image 之间可能有'",它还支持在可能根本没有url( 的HTML 和JS 文件中搜索。

    https://github.com/JayXon/Leanify

    【讨论】:

      【解决方案2】:

      基于 Python 的解决方案:

      #!/usr/bin/env python
      
      ''' Tool to optimize PNG images embedded as data URLs in CSS files or similar
      using ZopfliPNG.
      '''
      
      import base64
      import re
      import subprocess
      import sys
      import tempfile
      
      __author__ = "phk @ stackoverflow (https://stackoverflow.com/users/2261442)"
      __version__ = "1.0.1"
      
      # parameters for ZopfliPNG controlling the optimization method
      OPTIMIZATION_PARAMS = [
          "-m",
          "--lossy_transparent",
          "--iterations=1000"
      ]
      
      if len(sys.argv) < 2:
          print("Usage: {} ZOPFLIPNG_EXECUTABLE TARGET_FILES...".format(sys.argv[0]))
          sys.exit(1)
      
      zopflipng = sys.argv[1]
      targets = sys.argv[2:]
      
      # regex to match all the data urls with PNGs inside CSS or therelike
      # but only return the base64 encoded PNG data
      inline_png_re = re.compile(
          r"(?<=url\(data:image/png;base64,)[A-Za-z0-9+/]+=*(?=\))")
      
      # create temporary input/output files for ZopfliPNG, it only deals with files
      with tempfile.NamedTemporaryFile('w+b') as tmpf_in, \
              tempfile.NamedTemporaryFile('r+b') as tmpf_out:
      
          def replace_inline_png(match):
              ''' Replace all the PNGs inside data URLs with optimized versions. '''
      
              orig_data = match.group(0)
      
              try:
                  data = base64.b64decode(orig_data)
              except TypeError:
                  print("Invalid base64 string. Skipping this data URL.")
                  return orig_data
      
              # prepare input file for ZopfliPNG
              tmpf_in.seek(0)  # because the temporary input file gets re-used
              tmpf_in.truncate()
              tmpf_in.write(data)
              tmpf_in.flush()  # because the file is kept open
      
              tmpf_out.seek(0)
              tmpf_out.truncate()
      
              return_code = subprocess.call([
                  zopflipng,
                  "-y",  # silent overwriting of output file necessary
              ] + OPTIMIZATION_PARAMS + [
                  tmpf_in.name,
                  tmpf_out.name
              ])
      
              if return_code:
                  print("ZopfliPNG reported an error. Skipping this PNG.")
                  return orig_data
      
              # read zopflipng results from output file
              data = tmpf_out.read()
      
              return base64.b64encode(data)
      
          def optimize_file(target):
              ''' Optimize the PNGs embedded as data URLs in target file. '''
      
              try:
                  with open(target) as f_in:
                      contents = f_in.read()
              except IOError:
                  print("Can't open {} for reading!".format(target))
                  return
      
              # replace the inline PNGs with optimized versions
              contents = inline_png_re.sub(replace_inline_png, contents)
      
              try:
                  # write the changed file contents
                  with open(target, 'w') as f_out:
                      f_out.write(contents)
              except IOError:
                  print("Can't open {} for writing!".format(target))
                  return
      
          for target in targets:
              optimize_file(target)
      

      在输入和输出文件应该不同的假设下工作(根据我的测试,ZopfliPNG 也可以工作,输入和输出与您对程序的期望相同,但可以肯定的是,参数显然也似乎强制使用不同的输出文件)。在重复使用它创建的临时文件的同时进行了一些微优化。

      然后在带有 CSS/LESS/... 文件的文件夹上使用它,例如在 UNIX shell 中你可以这样做:

      find /css-folder/ -type f -name '*.*ss' -exec \
        /path/to/this_script_here.py /path/to/zopfli/zopflipng {} +
      

      【讨论】:

        猜你喜欢
        • 2013-07-06
        • 1970-01-01
        • 2015-03-07
        • 1970-01-01
        • 1970-01-01
        • 2016-07-08
        • 1970-01-01
        • 2015-06-15
        • 1970-01-01
        相关资源
        最近更新 更多