Skip to content
Browse files

- PNG optimizer changed to Trimage algorithm

- Output more useful details
  • Loading branch information...
1 parent 5f09e7f commit a56b11c5010c83bab8dd370b9b845cc41bb4c19d Marat Dyatko committed
Showing with 87 additions and 67 deletions.
  1. +21 −13 smush/optimiser/formats/png.py
  2. +59 −51 smush/optimiser/optimiser.py
  3. +7 −3 smush/smush.py
View
34 smush/optimiser/formats/png.py
@@ -12,24 +12,32 @@ def __init__(self, **kwargs):
super(OptimisePNG, self).__init__(**kwargs)
if kwargs.get('quiet') == True:
- pngcrush = 'pngcrush -rem alla -brute -reduce -q "__INPUT__" "__OUTPUT__"'
+ # pngcrush = 'pngcrush -rem alla -brute -reduce -q "__INPUT__" "__OUTPUT__"'
+ optipng = u"optipng -quiet -force -o7 '__INPUT__' -out '__OUTPUT__'"
+ advpng = u"advpng -z4 '__OUTPUT__'"
+ pngcrush = u"pngcrush -q -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time -ext '__OUTPUT__'"
else:
- pngcrush = 'pngcrush -rem alla -brute -reduce "__INPUT__" "__OUTPUT__"'
+ # pngcrush = 'pngcrush -rem alla -brute -reduce "__INPUT__" "__OUTPUT__"'
+ optipng = u"optipng -force -o7 '__INPUT__' -out '__OUTPUT__'"
+ advpng = u"advpng -z4 '__OUTPUT__'"
+ pngcrush = u"pngcrush -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time -ext '__OUTPUT__'"
+ rm = u"rm '__OUTPUT__'"
# the command to execute this optimiser
- self.commands = ('pngnq -n 256 -o "__OUTPUT__" "__INPUT__"', pngcrush)
+ #self.commands = ('pngnq -n 256 -o "__OUTPUT__" "__INPUT__"', pngcrush)
+ self.commands = (optipng,advpng,pngcrush,)
# format as returned by 'identify'
self.format = "PNG"
-# def _get_output_file_name(self):
-# """
-# Returns the input file name with Optimiser.output_suffix inserted before the extension
-# """
-# (basename, extension) = os.path.splitext(self.input)
-#
-# if extension.lower() == '.png':
-# return basename + Optimiser.output_suffix
-#
-# return self.input + Optimiser.output_suffix
+ def _get_output_file_name(self):
+ """
+ Returns the input file name with Optimiser.output_suffix inserted before the extension
+ """
+ (basename, extension) = os.path.splitext(self.input)
+
+ if extension.lower() == '.png':
+ return basename + Optimiser.output_suffix
+
+ return self.input + Optimiser.output_suffix
View
110 smush/optimiser/optimiser.py
@@ -74,28 +74,6 @@ def __replace_placeholders(self, command, input, output):
return command.replace(Optimiser.input_placeholder, input).replace(Optimiser.output_placeholder, output)
- def _keep_smallest_file(self, input, output):
- """
- Compares the sizes of two files, and discards the larger one
- """
- input_size = os.path.getsize(input)
- output_size = os.path.getsize(output)
-
- # if the image was optimised (output is smaller than input), overwrite the input file with the output
- # file.
- if (output_size > 0 and output_size < input_size):
- try:
- shutil.copyfile(output, input)
- self.files_optimised += 1
- self.bytes_saved += (input_size - output_size)
- except IOError:
- logging.error("Unable to copy %s to %s: %s" % (output, input, IOError))
- sys.exit(1)
-
- # delete the output file
- os.unlink(output)
-
-
def _is_acceptable_image(self, input):
"""
Returns whether the input image can be used by a particular optimiser.
@@ -138,43 +116,73 @@ def optimise(self):
while True:
command = self._get_command()
-
- if not command:
- break
-
output_file_name = self._get_output_file_name()
- command = self.__replace_placeholders(command, self.input, output_file_name)
- logging.info("Executing %s" % (command))
- args = shlex.split(command)
-
- try:
- retcode = subprocess.call(args, stdout=self.stdout.opened, stderr=self.stderr.opened)
- except OSError:
- logging.error("Error executing command %s. Error was %s" % (command, OSError))
- sys.exit(1)
-
- if retcode != 0:
- # gifsicle seems to fail by the file size?
- os.unlink(output_file_name)
- else :
- if self.list_only == False:
- # compare file sizes if the command executed successfully
- self._keep_smallest_file(self.input, output_file_name)
+
+ if command:
+ command = self.__replace_placeholders(command, self.input, output_file_name)
+ logging.info("Executing %s" % (command))
+ args = shlex.split(command)
+
+ try:
+ retcode = subprocess.call(args, stdout=self.stdout.opened, stderr=self.stderr.opened)
+ except OSError:
+ logging.error("Error executing command %s. Error was %s" % (command, OSError))
+ sys.exit(1)
+
+ if retcode != 0:
+ # gifsicle seems to fail by the file size?
+ if os.path.isfile(output_file_name):
+ os.unlink(output_file_name)
else:
+ if self.list_only == False:
+ # compare file sizes if the command executed successfully
+ self._keep_smallest_file(self.input, output_file_name)
+ else:
+ if self.list_only == True:
self._list_only(self.input, output_file_name)
+ if os.path.isfile(output_file_name):
+ os.unlink(output_file_name)
+ break
def _list_only(self, input, output):
"""
Always keeps input, but still compares the sizes of two files
"""
- input_size = os.path.getsize(input)
- output_size = os.path.getsize(output)
+ if os.path.isfile(input) and os.path.isfile(output):
+ input_size = os.path.getsize(input)
+ output_size = os.path.getsize(output)
+
+ if (output_size > 0 and output_size < input_size):
+ bytes_saved = (input_size - output_size)
+ self.files_optimised += 1
+ self.bytes_saved += bytes_saved
+
+ self.array_optimised_file.append({
+ 'name': input,
+ 'input_size': input_size,
+ 'output_size': output_size,
+ 'bytes_saved': bytes_saved,
+ 'bytes_saved_percent': int(100 - round((output_size / float(input_size)) * 100)),
+ })
- if (output_size > 0 and output_size < input_size):
- self.files_optimised += 1
- self.bytes_saved += (input_size - output_size)
- self.array_optimised_file.append(input)
+ def _keep_smallest_file(self, input, output):
+ """
+ Compares the sizes of two files, and discards the larger one
+ """
+ if os.path.isfile(input) and os.path.isfile(output):
+ input_size = os.path.getsize(input)
+ output_size = os.path.getsize(output)
+
+ # if the image was optimised (output is smaller than input), overwrite the input file with the output
+ # file.
+ if (output_size > 0 and output_size < input_size):
+ try:
+ shutil.copyfile(output, input)
+ self.files_optimised += 1
+ self.bytes_saved += (input_size - output_size)
+ except IOError:
+ logging.error("Unable to copy %s to %s: %s" % (output, input, IOError))
+ sys.exit(1)
- # delete the output file
- os.unlink(output)
+
View
10 smush/smush.py
@@ -139,12 +139,16 @@ def stats(self):
optimiser.bytes_saved / 1024))
arr.extend(optimiser.array_optimised_file)
+ modified = []
+
if (len(arr) != 0):
output.append('Modified files:')
- for filename in arr:
- output.append(' %s' % filename)
+ for f in arr:
+ if f['bytes_saved_percent']:
+ modified.append(f)
+ output.append('%(bytes_saved_percent)s%% saved\t[%(input_size)s / %(output_size)s]\t%(name)s' % f)
output.append('Total time taken: %.2f seconds' % (time.time() - self.__start_time))
- return {'output': "\n".join(output), 'modified': arr}
+ return {'output': "\n".join(output), 'modified': modified}
def __checkExclude(self, file):

0 comments on commit a56b11c

Please sign in to comment.
Something went wrong with that request. Please try again.