Merge branch 'master' into snapshot
This commit is contained in:
@@ -557,7 +557,9 @@ values. The valid configuration keys are listed below.
|
|||||||
The option is a list of Optimizer objects, which are then executed in
|
The option is a list of Optimizer objects, which are then executed in
|
||||||
the order in which they're specified::
|
the order in which they're specified::
|
||||||
|
|
||||||
|
# Import the optimizers we need
|
||||||
from optimizeimages import pngnq, optipng
|
from optimizeimages import pngnq, optipng
|
||||||
|
|
||||||
worlds["world"] = "/path/to/world"
|
worlds["world"] = "/path/to/world"
|
||||||
|
|
||||||
renders["daytime"] = {
|
renders["daytime"] = {
|
||||||
@@ -566,6 +568,10 @@ values. The valid configuration keys are listed below.
|
|||||||
"rendermode":smooth_lighting,
|
"rendermode":smooth_lighting,
|
||||||
"optimizeimg":[pngnq(sampling=1), optipng(olevel=3)],
|
"optimizeimg":[pngnq(sampling=1), optipng(olevel=3)],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Don't forget to import the optimizers you use in your config file, as shown in the
|
||||||
|
example above.
|
||||||
|
|
||||||
Here is a list of supported image optimization programs:
|
Here is a list of supported image optimization programs:
|
||||||
|
|
||||||
@@ -612,8 +618,9 @@ values. The valid configuration keys are listed below.
|
|||||||
**Default:** ``2``
|
**Default:** ``2``
|
||||||
|
|
||||||
``pngcrush``
|
``pngcrush``
|
||||||
pngcrush is very slow and not very good, you should use optipng in probably all cases.
|
pngcrush, like optipng, is a lossless PNG recompressor. If you are able to do so, it
|
||||||
However, Overviewer still allows you to use it because we're nice people like that.
|
is recommended to use optipng instead, as it generally yields better results in less
|
||||||
|
time.
|
||||||
Available settings:
|
Available settings:
|
||||||
|
|
||||||
``brute``
|
``brute``
|
||||||
@@ -626,10 +633,6 @@ values. The valid configuration keys are listed below.
|
|||||||
|
|
||||||
**Default:** ``False``
|
**Default:** ``False``
|
||||||
|
|
||||||
.. note::
|
|
||||||
Don't forget to import the optimizers you use in your settings file, as shown in the
|
|
||||||
example above.
|
|
||||||
|
|
||||||
**Default:** ``[]``
|
**Default:** ``[]``
|
||||||
|
|
||||||
``bgcolor``
|
``bgcolor``
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ class Optimizer:
|
|||||||
|
|
||||||
if (not exists_in_path(self.binaryname)) and (not exists_in_path(self.binaryname + ".exe")):
|
if (not exists_in_path(self.binaryname)) and (not exists_in_path(self.binaryname + ".exe")):
|
||||||
raise Exception("Optimization program '%s' was not found!" % self.binaryname)
|
raise Exception("Optimization program '%s' was not found!" % self.binaryname)
|
||||||
|
|
||||||
|
def is_crusher(self):
|
||||||
|
"""Should return True if the optimization is lossless, i.e. none of the actual image data will be changed."""
|
||||||
|
raise NotImplementedError("I'm so abstract I can't even say whether I'm a crusher.")
|
||||||
|
|
||||||
|
|
||||||
class NonAtomicOptimizer(Optimizer):
|
class NonAtomicOptimizer(Optimizer):
|
||||||
@@ -84,6 +88,9 @@ class pngnq(NonAtomicOptimizer, PNGOptimizer):
|
|||||||
|
|
||||||
NonAtomicOptimizer.fire_and_forget(self, args, img)
|
NonAtomicOptimizer.fire_and_forget(self, args, img)
|
||||||
|
|
||||||
|
def is_crusher(self):
|
||||||
|
return False
|
||||||
|
|
||||||
class pngcrush(NonAtomicOptimizer, PNGOptimizer):
|
class pngcrush(NonAtomicOptimizer, PNGOptimizer):
|
||||||
binaryname = "pngcrush"
|
binaryname = "pngcrush"
|
||||||
# really can't be bothered to add some interface for all
|
# really can't be bothered to add some interface for all
|
||||||
@@ -98,6 +105,9 @@ class pngcrush(NonAtomicOptimizer, PNGOptimizer):
|
|||||||
|
|
||||||
NonAtomicOptimizer.fire_and_forget(self, args, img)
|
NonAtomicOptimizer.fire_and_forget(self, args, img)
|
||||||
|
|
||||||
|
def is_crusher(self):
|
||||||
|
return True
|
||||||
|
|
||||||
class optipng(Optimizer, PNGOptimizer):
|
class optipng(Optimizer, PNGOptimizer):
|
||||||
binaryname = "optipng"
|
binaryname = "optipng"
|
||||||
|
|
||||||
@@ -106,6 +116,9 @@ class optipng(Optimizer, PNGOptimizer):
|
|||||||
|
|
||||||
def optimize(self, img):
|
def optimize(self, img):
|
||||||
Optimizer.fire_and_forget(self, [self.binaryname, "-o" + str(self.olevel), "-quiet", img])
|
Optimizer.fire_and_forget(self, [self.binaryname, "-o" + str(self.olevel), "-quiet", img])
|
||||||
|
|
||||||
|
def is_crusher(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def optimize_image(imgpath, imgformat, optimizers):
|
def optimize_image(imgpath, imgformat, optimizers):
|
||||||
|
|||||||
@@ -160,15 +160,25 @@ def validateBGColor(color):
|
|||||||
def validateOptImg(optimizers):
|
def validateOptImg(optimizers):
|
||||||
if isinstance(optimizers, (int, long)):
|
if isinstance(optimizers, (int, long)):
|
||||||
from optimizeimages import pngcrush
|
from optimizeimages import pngcrush
|
||||||
logging.warning("You're using a deprecated definition of optimizeimg. We'll do what you say for now, but please fix this as soon as possible.")
|
logging.warning("You're using a deprecated definition of optimizeimg. "\
|
||||||
|
"We'll do what you say for now, but please fix this as soon as possible.")
|
||||||
optimizers = [pngcrush()]
|
optimizers = [pngcrush()]
|
||||||
if not isinstance(optimizers, list):
|
if not isinstance(optimizers, list):
|
||||||
raise ValidationException("optimizeimg is not a list. Make sure you specify them like [foo()], with square brackets.")
|
raise ValidationException("What you passed to optimizeimg is not a list. "\
|
||||||
for opt in optimizers:
|
"Make sure you specify them like [foo()], with square brackets.")
|
||||||
if not isinstance(opt, Optimizer):
|
|
||||||
raise ValidationException("Invalid Optimizer!")
|
|
||||||
|
|
||||||
opt.check_availability()
|
if optimizers:
|
||||||
|
for opt, next_opt in zip(optimizers, optimizers[1:]) + [(optimizers[-1], None)]:
|
||||||
|
if not isinstance(opt, Optimizer):
|
||||||
|
raise ValidationException("Invalid Optimizer!")
|
||||||
|
|
||||||
|
opt.check_availability()
|
||||||
|
|
||||||
|
# Check whether the chaining is somewhat sane
|
||||||
|
if next_opt:
|
||||||
|
if opt.is_crusher() and not next_opt.is_crusher():
|
||||||
|
logging.warning("You're feeding a crushed output into an optimizer that does not crush. "\
|
||||||
|
"This is most likely pointless, and wastes time.")
|
||||||
|
|
||||||
return optimizers
|
return optimizers
|
||||||
|
|
||||||
|
|||||||
@@ -161,17 +161,6 @@ class Textures(object):
|
|||||||
return None
|
return None
|
||||||
if verbose: logging.info('search_zip_paths: ' + ', '.join(search_zip_paths))
|
if verbose: logging.info('search_zip_paths: ' + ', '.join(search_zip_paths))
|
||||||
|
|
||||||
# we've sucessfully loaded something from here before, so let's quickly try
|
|
||||||
# this before searching again
|
|
||||||
if self.jar is not None:
|
|
||||||
for jarfilename in search_zip_paths:
|
|
||||||
try:
|
|
||||||
self.jar.getinfo(jarfilename)
|
|
||||||
if verbose: logging.info("Found (cached) %s in '%s'", jarfilename, self.jarpath)
|
|
||||||
return self.jar.open(jarfilename)
|
|
||||||
except (KeyError, IOError), e:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# A texture path was given on the command line. Search this location
|
# A texture path was given on the command line. Search this location
|
||||||
# for the file first.
|
# for the file first.
|
||||||
if self.find_file_local_path:
|
if self.find_file_local_path:
|
||||||
@@ -227,6 +216,17 @@ class Textures(object):
|
|||||||
if verbose: logging.info("Did not find the file in overviewer executable directory")
|
if verbose: logging.info("Did not find the file in overviewer executable directory")
|
||||||
if verbose: logging.info("Looking for installed minecraft jar files...")
|
if verbose: logging.info("Looking for installed minecraft jar files...")
|
||||||
|
|
||||||
|
# we've sucessfully loaded something from here before, so let's quickly try
|
||||||
|
# this before searching again
|
||||||
|
if self.jar is not None:
|
||||||
|
for jarfilename in search_zip_paths:
|
||||||
|
try:
|
||||||
|
self.jar.getinfo(jarfilename)
|
||||||
|
if verbose: logging.info("Found (cached) %s in '%s'", jarfilename, self.jarpath)
|
||||||
|
return self.jar.open(jarfilename)
|
||||||
|
except (KeyError, IOError), e:
|
||||||
|
pass
|
||||||
|
|
||||||
# Find an installed minecraft client jar and look in it for the texture
|
# Find an installed minecraft client jar and look in it for the texture
|
||||||
# file we need.
|
# file we need.
|
||||||
versiondir = ""
|
versiondir = ""
|
||||||
|
|||||||
Reference in New Issue
Block a user