Skip to content

Instantly share code, notes, and snippets.

@harto
Created October 15, 2013 20:28
Show Gist options
  • Save harto/6998135 to your computer and use it in GitHub Desktop.
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.
#!/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