|
@@ -6,9 +6,12 @@ Contains classes to handle images related things |
|
|
""" |
|
|
""" |
|
|
|
|
|
|
|
|
from hyde.plugin import Plugin |
|
|
from hyde.plugin import Plugin |
|
|
|
|
|
from hyde.fs import File, Folder |
|
|
|
|
|
|
|
|
import re |
|
|
import re |
|
|
import Image |
|
|
import Image |
|
|
|
|
|
import glob |
|
|
|
|
|
import os |
|
|
|
|
|
|
|
|
class ImageSizerPlugin(Plugin): |
|
|
class ImageSizerPlugin(Plugin): |
|
|
""" |
|
|
""" |
|
@@ -145,3 +148,97 @@ class ImageSizerPlugin(Plugin): |
|
|
continue |
|
|
continue |
|
|
|
|
|
|
|
|
return text |
|
|
return text |
|
|
|
|
|
|
|
|
|
|
|
class ImageThumbnailsPlugin(Plugin): |
|
|
|
|
|
""" |
|
|
|
|
|
Provide a function to get thumbnail for any image resource. |
|
|
|
|
|
|
|
|
|
|
|
Example of usage: |
|
|
|
|
|
Setting optional defaults in site.yaml: |
|
|
|
|
|
thumbnails: |
|
|
|
|
|
width: 100 |
|
|
|
|
|
height: 120 |
|
|
|
|
|
prefix: thumbnail_ |
|
|
|
|
|
|
|
|
|
|
|
Setting thumbnails options in nodemeta.yaml: |
|
|
|
|
|
thumbnails: |
|
|
|
|
|
- width: 50 |
|
|
|
|
|
prefix: thumbs1_ |
|
|
|
|
|
include: |
|
|
|
|
|
- '*.png' |
|
|
|
|
|
- '*.jpg' |
|
|
|
|
|
- height: 100 |
|
|
|
|
|
prefix: thumbs2_ |
|
|
|
|
|
include: |
|
|
|
|
|
- '*.png' |
|
|
|
|
|
- '*.jpg' |
|
|
|
|
|
which means - make from every picture two thumbnails with different prefixes |
|
|
|
|
|
and sizes |
|
|
|
|
|
|
|
|
|
|
|
Currently, only supports PNG and JPG. |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, site): |
|
|
|
|
|
super(ImageThumbnailsPlugin, self).__init__(site) |
|
|
|
|
|
|
|
|
|
|
|
def thumb(self, resource, width, height, prefix): |
|
|
|
|
|
""" |
|
|
|
|
|
Generate a thumbnail for the given image |
|
|
|
|
|
""" |
|
|
|
|
|
# Prepare path |
|
|
|
|
|
path = os.path.join(os.path.dirname(resource.get_relative_deploy_path()), |
|
|
|
|
|
"%s%s" % (prefix, os.path.basename(resource.get_relative_deploy_path()))) |
|
|
|
|
|
target = File(Folder(resource.site.config.deploy_root_path).child(path)) |
|
|
|
|
|
target.parent.make() |
|
|
|
|
|
if os.path.exists(target.path) and os.path.getmtime(resource.path) <= os.path.getmtime(target.path): |
|
|
|
|
|
return |
|
|
|
|
|
self.logger.debug("Making thumbnail for [%s]" % resource) |
|
|
|
|
|
|
|
|
|
|
|
im = Image.open(resource.path) |
|
|
|
|
|
if im.mode != 'RGBA': |
|
|
|
|
|
im = im.convert('RGBA') |
|
|
|
|
|
# Convert to a thumbnail |
|
|
|
|
|
if width is None: |
|
|
|
|
|
# height is not None |
|
|
|
|
|
width = im.size[0]*height/im.size[1] + 1 |
|
|
|
|
|
elif height is None: |
|
|
|
|
|
# width is not None |
|
|
|
|
|
height = im.size[1]*width/im.size[0] + 1 |
|
|
|
|
|
im.thumbnail((width, height), Image.ANTIALIAS) |
|
|
|
|
|
if resource.name.endswith(".jpg"): |
|
|
|
|
|
im.save(target.path, "JPEG", optimize=True, quality=75) |
|
|
|
|
|
else: |
|
|
|
|
|
im.save(target.path, "PNG", optimize=True) |
|
|
|
|
|
|
|
|
|
|
|
def begin_site(self): |
|
|
|
|
|
""" |
|
|
|
|
|
Find any image resource to add them the thumb() function. |
|
|
|
|
|
""" |
|
|
|
|
|
# Grab default values from config |
|
|
|
|
|
config = self.site.config |
|
|
|
|
|
defaults = { "width": None, |
|
|
|
|
|
"height": None, |
|
|
|
|
|
"prefix": 'thumb_'} |
|
|
|
|
|
if hasattr(config, 'thumbnails'): |
|
|
|
|
|
defaults.update(config.thumbnails) |
|
|
|
|
|
|
|
|
|
|
|
for node in self.site.content.walk(): |
|
|
|
|
|
if hasattr(node, 'meta') and hasattr(node.meta, 'thumbnails'): |
|
|
|
|
|
for th in node.meta.thumbnails: |
|
|
|
|
|
if not hasattr(th, 'include'): |
|
|
|
|
|
self.logger.error("Include is not set for node [%s]" % node) |
|
|
|
|
|
continue |
|
|
|
|
|
include = th.include |
|
|
|
|
|
prefix = th.prefix if hasattr(th, 'prefix') else defaults['prefix'] |
|
|
|
|
|
height = th.height if hasattr(th, 'height') else defaults['height'] |
|
|
|
|
|
width = th.width if hasattr(th, 'width') else defaults['width'] |
|
|
|
|
|
if width is None and height is None: |
|
|
|
|
|
self.logger.error("Both width and height are not set for node [%s]" % node) |
|
|
|
|
|
continue |
|
|
|
|
|
thumbs_list = [] |
|
|
|
|
|
for inc in include: |
|
|
|
|
|
for path in glob.glob(node.path + os.sep + inc): |
|
|
|
|
|
thumbs_list.append(path) |
|
|
|
|
|
for resource in node.resources: |
|
|
|
|
|
if resource.source_file.kind in ["jpg", "png"] and resource.path in thumbs_list: |
|
|
|
|
|
self.thumb(resource, width, height, prefix) |