terom@51: """ terom@51: Rendering images as thumbnails/previews. terom@51: """ terom@51: terom@51: import PIL.Image terom@51: terom@51: class RenderMachine (object) : terom@51: """ terom@51: RAWR! I'm the render machine! terom@51: terom@51: TODO: use multithreaded rendering (PIL supports it) terom@51: """ terom@51: terom@51: def __init__ (self, config) : terom@51: """ terom@51: Use the given Configuration object's settings for rendering terom@51: """ terom@51: terom@51: self.config = config terom@51: terom@57: def render_out (self, image, size, file) : terom@51: """ terom@57: Creates a thumbnail from the given Image of the given `size`, and saves it at `out`. terom@57: terom@57: Returns the file for convenience terom@51: """ terom@51: terom@57: # load the PIL.Image terom@77: img = image.image terom@57: terom@51: # we need to create a copy, as .thumbnail mutates the Image terom@51: img_out = img.copy() terom@51: terom@51: # then resample to given size terom@51: img_out.thumbnail(size, resample=True) terom@51: terom@51: # and write out terom@57: img_out.save(file.path) terom@51: terom@57: return file terom@57: terom@57: def render_lazy (self, image, size, out) : terom@51: """ terom@57: Renders the given image with render_out if `out` does not yet exist or is older than image. terom@51: """ terom@51: terom@57: # stat the output file terom@57: out_stat = out.stat(soft=True) terom@51: terom@57: # compare terom@77: if not out_stat or out_stat.st_mtime < image.stat.st_mtime : terom@57: # render anew terom@77: return self.render_out(image, size, out) terom@57: terom@57: else : terom@57: # already rendered terom@77: return out