使用ZopfliPNG自动优化CSS文件(数据URI)内的PNG

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

可悲的是,ZopfliPNG似乎只能处理文件,而不能处理stdin / stdout(像“支持管道输入”这样的bug跟踪器条目仍处于打开状态),这使事情变得更加复杂。


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

它比你的python脚本有一些优点:

  • 它还支持其他图像格式,如JPEG,ICO和SVG。

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

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

  • https://github.com/JayXon/Leanify


    基于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 {} +
    
    链接地址: http://www.djcxy.com/p/31853.html

    上一篇: Automated optimization of PNGs inside CSS files (data URIs) using ZopfliPNG

    下一篇: content security policy issue with chrome extension