使用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