Skip to content

Commit

Permalink
Improve 'resizer' function discovering in 'moviepy.video.fx.resize' (Z…
Browse files Browse the repository at this point in the history
…ulko#1444)

* Fix flake8 errors

* Empty commit to rerun CI

* Fix error message
  • Loading branch information
mondeja committed Jan 18, 2021
1 parent 7c3dc0a commit 2066244
Showing 1 changed file with 98 additions and 33 deletions.
131 changes: 98 additions & 33 deletions moviepy/video/fx/resize.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
resize_possible = True

try:
# TRY USING OpenCV AS RESIZER
# raise ImportError #debugging
import cv2
import numpy as np
def _get_cv2_resizer():
try:
import cv2
except ImportError:
return (None, ["OpenCV not found (install 'opencv-python')"])

def resizer(pic, new_size):
lx, ly = int(new_size[0]), int(new_size[1])
Expand All @@ -16,43 +14,105 @@ def resizer(pic, new_size):
interpolation = cv2.INTER_AREA
return cv2.resize(+pic.astype("uint8"), (lx, ly), interpolation=interpolation)

resizer.origin = "cv2"
return (resizer, [])

except ImportError:

def _get_PIL_resizer():
try:
# TRY USING PIL/PILLOW AS RESIZER
from PIL import Image
import numpy as np
except ImportError:
return (None, ["PIL not found (install 'Pillow')"])

def resizer(pic, new_size):
new_size = list(map(int, new_size))[::-1]
# shape = pic.shape
# if len(shape) == 3:
# newshape = (new_size[0], new_size[1], shape[2])
# else:
# newshape = (new_size[0], new_size[1])
import numpy as np

pil_img = Image.fromarray(pic)
resized_pil = pil_img.resize(new_size[::-1], Image.ANTIALIAS)
# arr = np.fromstring(resized_pil.tostring(), dtype='uint8')
# arr.reshape(newshape)
return np.array(resized_pil)
def resizer(pic, new_size):
new_size = list(map(int, new_size))[::-1]
# shape = pic.shape
# if len(shape) == 3:
# newshape = (new_size[0], new_size[1], shape[2])
# else:
# newshape = (new_size[0], new_size[1])

resizer.origin = "PIL"
pil_img = Image.fromarray(pic)
resized_pil = pil_img.resize(new_size[::-1], Image.ANTIALIAS)
# arr = np.fromstring(resized_pil.tostring(), dtype="uint8")
# arr.reshape(newshape)
return np.array(resized_pil)

return (resizer, [])


def _get_scipy_resizer():
try:
from scipy.misc import imresize
except ImportError:
# TRY USING SCIPY AS RESIZER
try:
from scipy.misc import imresize
from scipy import __version__ as __scipy_version__
except ImportError:
return (None, ["Scipy not found (install 'scipy' or 'Pillow')"])

scipy_version_info = tuple(
int(num) for num in __scipy_version__.split(".") if num.isdigit()
)

# ``scipy.misc.imresize`` was removed in v1.3.0
if scipy_version_info >= (1, 3, 0):
return (
None,
[
"scipy.misc.imresize not found (was removed in scipy v1.3.0,"
f" you are using v{__scipy_version__}, install 'Pillow')"
],
)

# unknown reason
return (None, "scipy.misc.imresize not found")

def resizer(pic, new_size):
return imresize(pic, map(int, new_size[::-1]))
def resizer(pic, new_size):
return imresize(pic, map(int, new_size[::-1]))

resizer.origin = "Scipy"
return (resizer, [])

except ImportError:
resize_possible = False

def _get_resizer():
"""Tries to define a ``resizer`` function using next libraries, in the given
order:
- cv2
- PIL
- scipy
Returns a dictionary with following attributes:
- ``resizer``: Function used to resize images in ``resize`` FX function.
- ``origin``: Library used to resize.
- ``error_msgs``: If any of the libraries is available, shows the user why
this feature is not available and how to fix it in several error messages
which are formatted in the error displayed, if resizing is not possible.
"""
error_messages = []

resizer_getters = {
"cv2": _get_cv2_resizer,
"PIL": _get_PIL_resizer,
"scipy": _get_scipy_resizer,
}
for origin, resizer_getter in resizer_getters.items():
resizer, _error_messages = resizer_getter()
if resizer is not None:
return {"resizer": resizer, "origin": origin, "error_msgs": []}
else:
error_messages.extend(_error_messages)

return {"resizer": None, "origin": None, "error_msgs": reversed(error_messages)}


resizer = None
_resizer_data = _get_resizer()
if _resizer_data["resizer"] is not None:
resizer = _resizer_data["resizer"]
resizer.origin = _resizer_data["origin"]
del _resizer_data["error_msgs"]


def resize(clip, new_size=None, height=None, width=None, apply_to_mask=True):
Expand Down Expand Up @@ -174,10 +234,15 @@ def image_filter(pic):
return new_clip


if not resize_possible:
if resizer is None:
del resizer

doc = resize.__doc__

def resize(clip, new_size=None, height=None, width=None):
raise ImportError("fx resize needs OpenCV or Scipy or PIL")
fix_tips = "- " + "\n- ".join(_resizer_data["error_msgs"])
raise ImportError(f"fx resize needs OpenCV or Scipy or PIL\n{fix_tips}")

resize.__doc__ = doc

del _resizer_data["origin"], _resizer_data["resizer"]

0 comments on commit 2066244

Please sign in to comment.