Created
October 15, 2013 20:28
-
-
Save harto/6998135 to your computer and use it in GitHub Desktop.
A multiplexing Thumbor engine that prefers OpenCV where possible, and falls back to Pillow for unsupported image types.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
# Licensed under the MIT license: | |
# http://www.opensource.org/licenses/mit-license | |
# Copyright (c) 2013 arthens@gmail.com | |
import magic | |
from thumbor.engines import pil, opencv | |
class Engine: | |
def __init__(self, context): | |
self.opencv = opencv.Engine(context) | |
self.pil = pil.Engine(context) | |
self.activeEngine = None | |
def __getattr__(self, item): | |
return getattr(self.activeEngine, item) | |
def load(self, buffer, extension): | |
if self._use_opencv(buffer): | |
self.opencv.load(buffer, extension) | |
self.activeEngine = self.opencv | |
else: | |
self.pil.load(buffer, extension) | |
self.activeEngine = self.pil | |
def _use_opencv(self, buffer): | |
""" | |
Determine if buffer can be resized using OpenCV. OpenCV can't handle | |
GIFs, or PNGs with alpha transparency, but is much faster than the other | |
engine implementations. | |
""" | |
file_description = self._describe_contents(buffer) | |
return 'GIF' not in file_description and 'RGBA' not in file_description | |
def _describe_contents(self, buffer): | |
""" | |
Use libmagic to get a string describing the contents of buffer. | |
""" | |
# There are two Python libraries that wrap libmagic: python-magic[1] and | |
# magic-python[2]. Both define the module `magic`. Thumbor already uses | |
# python-magic, but due to a packaging issue[3] magic-python is included | |
# when Thumbor is installed as a package (e.g. via apt-get). | |
# | |
# Due to this unfortunate series of events, we can't predict which | |
# library is available ahead of time. Instead we have to detect at | |
# runtime and respond accordingly. | |
# | |
# [1]: https://github.com/ahupp/python-magic | |
# [2]: https://github.com/mammadori/magic-python | |
# [3]: https://github.com/globocom/thumbor/issues/188 | |
try: | |
# python-magic | |
return magic.from_buffer(buffer) | |
except AttributeError: | |
# magic-python | |
m = magic.open(magic.NONE) | |
m.load() | |
result = m.buffer(buffer) | |
m.close() | |
return result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment