166 lines
4.8 KiB
Python
166 lines
4.8 KiB
Python
|
resize_possible = True
|
||
|
|
||
|
try:
|
||
|
# TRY USING OpenCV AS RESIZER
|
||
|
#raise ImportError #debugging
|
||
|
import cv2
|
||
|
import numpy as np
|
||
|
def resizer (pic, newsize):
|
||
|
lx, ly = int(newsize[0]), int(newsize[1])
|
||
|
if lx > pic.shape[1] or ly > pic.shape[0]:
|
||
|
# For upsizing use linear for good quality & decent speed
|
||
|
interpolation = cv2.INTER_LINEAR
|
||
|
else:
|
||
|
# For dowsizing use area to prevent aliasing
|
||
|
interpolation = cv2.INTER_AREA
|
||
|
return cv2.resize(+pic.astype('uint8'), (lx, ly),
|
||
|
interpolation=interpolation)
|
||
|
|
||
|
resizer.origin = "cv2"
|
||
|
|
||
|
except ImportError:
|
||
|
|
||
|
|
||
|
try:
|
||
|
# TRY USING PIL/PILLOW AS RESIZER
|
||
|
from PIL import Image
|
||
|
import numpy as np
|
||
|
def resizer(pic, newsize):
|
||
|
newsize = list(map(int, newsize))[::-1]
|
||
|
shape = pic.shape
|
||
|
if len(shape)==3:
|
||
|
newshape = (newsize[0],newsize[1], shape[2] )
|
||
|
else:
|
||
|
newshape = (newsize[0],newsize[1])
|
||
|
|
||
|
pilim = Image.fromarray(pic)
|
||
|
resized_pil = pilim.resize(newsize[::-1], Image.ANTIALIAS)
|
||
|
#arr = np.fromstring(resized_pil.tostring(), dtype='uint8')
|
||
|
#arr.reshape(newshape)
|
||
|
return np.array(resized_pil)
|
||
|
|
||
|
resizer.origin = "PIL"
|
||
|
|
||
|
except ImportError:
|
||
|
# TRY USING SCIPY AS RESIZER
|
||
|
try:
|
||
|
from scipy.misc import imresize
|
||
|
resizer = lambda pic, newsize : imresize(pic,
|
||
|
map(int, newsize[::-1]))
|
||
|
resizer.origin = "Scipy"
|
||
|
|
||
|
except ImportError:
|
||
|
resize_possible = False
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
from moviepy.decorators import apply_to_mask
|
||
|
|
||
|
|
||
|
def resize(clip, newsize=None, height=None, width=None, apply_to_mask=True):
|
||
|
"""
|
||
|
Returns a video clip that is a resized version of the clip.
|
||
|
|
||
|
Parameters
|
||
|
------------
|
||
|
|
||
|
newsize:
|
||
|
Can be either
|
||
|
- ``(width,height)`` in pixels or a float representing
|
||
|
- A scaling factor, like 0.5
|
||
|
- A function of time returning one of these.
|
||
|
|
||
|
width:
|
||
|
width of the new clip in pixel. The height is then computed so
|
||
|
that the width/height ratio is conserved.
|
||
|
|
||
|
height:
|
||
|
height of the new clip in pixel. The width is then computed so
|
||
|
that the width/height ratio is conserved.
|
||
|
|
||
|
Examples
|
||
|
----------
|
||
|
|
||
|
>>> myClip.resize( (460,720) ) # New resolution: (460,720)
|
||
|
>>> myClip.resize(0.6) # width and heigth multiplied by 0.6
|
||
|
>>> myClip.resize(width=800) # height computed automatically.
|
||
|
>>> myClip.resize(lambda t : 1+0.02*t) # slow swelling of the clip
|
||
|
|
||
|
"""
|
||
|
|
||
|
w, h = clip.size
|
||
|
|
||
|
if newsize is not None:
|
||
|
|
||
|
def trans_newsize(ns):
|
||
|
|
||
|
if isinstance(ns, (int, float)):
|
||
|
return [ns * w, ns * h]
|
||
|
else:
|
||
|
return ns
|
||
|
|
||
|
if hasattr(newsize, "__call__"):
|
||
|
|
||
|
newsize2 = lambda t : trans_newsize(newsize(t))
|
||
|
|
||
|
if clip.ismask:
|
||
|
|
||
|
fun = lambda gf,t: (1.0*resizer((255 * gf(t)).astype('uint8'),
|
||
|
newsize2(t))/255)
|
||
|
else:
|
||
|
|
||
|
fun = lambda gf,t: resizer(gf(t).astype('uint8'),
|
||
|
newsize2(t))
|
||
|
|
||
|
return clip.fl(fun, keep_duration=True,
|
||
|
apply_to= (["mask"] if apply_to_mask else []))
|
||
|
|
||
|
else:
|
||
|
|
||
|
newsize = trans_newsize(newsize)
|
||
|
|
||
|
|
||
|
elif height is not None:
|
||
|
|
||
|
if hasattr(height, "__call__"):
|
||
|
fun = lambda t : 1.0*int(height(t))/h
|
||
|
return resize(clip, fun)
|
||
|
|
||
|
|
||
|
else:
|
||
|
|
||
|
newsize = [w * height / h, height]
|
||
|
|
||
|
elif width is not None:
|
||
|
|
||
|
if hasattr(width, "__call__"):
|
||
|
fun = lambda t : 1.0*width(t)/w
|
||
|
return resize(clip, fun)
|
||
|
|
||
|
newsize = [width, h * width / w]
|
||
|
|
||
|
|
||
|
# From here, the resizing is constant (not a function of time), size=newsize
|
||
|
|
||
|
if clip.ismask:
|
||
|
fl = lambda pic: 1.0*resizer((255 * pic).astype('uint8'), newsize)/255.0
|
||
|
|
||
|
else:
|
||
|
fl = lambda pic: resizer(pic.astype('uint8'), newsize)
|
||
|
|
||
|
newclip = clip.fl_image(fl)
|
||
|
|
||
|
if apply_to_mask and clip.mask is not None:
|
||
|
newclip.mask = resize(clip.mask, newsize, apply_to_mask=False)
|
||
|
|
||
|
return newclip
|
||
|
|
||
|
|
||
|
if not resize_possible:
|
||
|
|
||
|
doc = resize.__doc__
|
||
|
def resize(clip, newsize=None, height=None, width=None):
|
||
|
raise ImportError("fx resize needs OpenCV or Scipy or PIL")
|
||
|
resize.__doc__ = doc
|