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であなたができるシェル:
find /css-folder/ -type f -name '*.*ss' -exec \
/path/to/this_script_here.py /path/to/zopfli/zopflipng {} +
出典
2016-07-13 13:53:12
phk