mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-05-04 07:53:40 +03:00
Fast paths for rotation
This commit is contained in:
parent
f680b5417b
commit
8203a43d26
22
PIL/Image.py
22
PIL/Image.py
|
@ -1569,6 +1569,18 @@ class Image(object):
|
||||||
:returns: An :py:class:`~PIL.Image.Image` object.
|
:returns: An :py:class:`~PIL.Image.Image` object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
angle = angle % 360.0
|
||||||
|
|
||||||
|
# Fast paths regardless of filter
|
||||||
|
if angle == 0:
|
||||||
|
return self._new(self.im)
|
||||||
|
if angle == 180:
|
||||||
|
return self.transpose(ROTATE_180)
|
||||||
|
if angle == 90 and expand:
|
||||||
|
return self.transpose(ROTATE_90)
|
||||||
|
if angle == 270 and expand:
|
||||||
|
return self.transpose(ROTATE_270)
|
||||||
|
|
||||||
if expand:
|
if expand:
|
||||||
import math
|
import math
|
||||||
angle = -angle * math.pi / 180
|
angle = -angle * math.pi / 180
|
||||||
|
@ -1843,9 +1855,11 @@ class Image(object):
|
||||||
|
|
||||||
if isinstance(method, ImageTransformHandler):
|
if isinstance(method, ImageTransformHandler):
|
||||||
return method.transform(size, self, resample=resample, fill=fill)
|
return method.transform(size, self, resample=resample, fill=fill)
|
||||||
|
|
||||||
if hasattr(method, "getdata"):
|
if hasattr(method, "getdata"):
|
||||||
# compatibility w. old-style transform objects
|
# compatibility w. old-style transform objects
|
||||||
method, data = method.getdata()
|
method, data = method.getdata()
|
||||||
|
|
||||||
if data is None:
|
if data is None:
|
||||||
raise ValueError("missing method data")
|
raise ValueError("missing method data")
|
||||||
|
|
||||||
|
@ -1864,13 +1878,14 @@ class Image(object):
|
||||||
|
|
||||||
# FIXME: this should be turned into a lazy operation (?)
|
# FIXME: this should be turned into a lazy operation (?)
|
||||||
|
|
||||||
w = box[2]-box[0]
|
w = box[2] - box[0]
|
||||||
h = box[3]-box[1]
|
h = box[3] - box[1]
|
||||||
|
|
||||||
if method == AFFINE:
|
if method == AFFINE:
|
||||||
# change argument order to match implementation
|
# change argument order to match implementation
|
||||||
data = (data[2], data[0], data[1],
|
data = (data[2], data[0], data[1],
|
||||||
data[5], data[3], data[4])
|
data[5], data[3], data[4])
|
||||||
|
|
||||||
elif method == EXTENT:
|
elif method == EXTENT:
|
||||||
# convert extent to an affine transform
|
# convert extent to an affine transform
|
||||||
x0, y0, x1, y1 = data
|
x0, y0, x1, y1 = data
|
||||||
|
@ -1878,11 +1893,13 @@ class Image(object):
|
||||||
ys = float(y1 - y0) / h
|
ys = float(y1 - y0) / h
|
||||||
method = AFFINE
|
method = AFFINE
|
||||||
data = (x0 + xs/2, xs, 0, y0 + ys/2, 0, ys)
|
data = (x0 + xs/2, xs, 0, y0 + ys/2, 0, ys)
|
||||||
|
|
||||||
elif method == PERSPECTIVE:
|
elif method == PERSPECTIVE:
|
||||||
# change argument order to match implementation
|
# change argument order to match implementation
|
||||||
data = (data[2], data[0], data[1],
|
data = (data[2], data[0], data[1],
|
||||||
data[5], data[3], data[4],
|
data[5], data[3], data[4],
|
||||||
data[6], data[7])
|
data[6], data[7])
|
||||||
|
|
||||||
elif method == QUAD:
|
elif method == QUAD:
|
||||||
# quadrilateral warp. data specifies the four corners
|
# quadrilateral warp. data specifies the four corners
|
||||||
# given as NW, SW, SE, and NE.
|
# given as NW, SW, SE, and NE.
|
||||||
|
@ -1897,6 +1914,7 @@ class Image(object):
|
||||||
(se[0]-sw[0]-ne[0]+x0)*As*At,
|
(se[0]-sw[0]-ne[0]+x0)*As*At,
|
||||||
y0, (ne[1]-y0)*As, (sw[1]-y0)*At,
|
y0, (ne[1]-y0)*As, (sw[1]-y0)*At,
|
||||||
(se[1]-sw[1]-ne[1]+y0)*As*At)
|
(se[1]-sw[1]-ne[1]+y0)*As*At)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("unknown transformation method")
|
raise ValueError("unknown transformation method")
|
||||||
|
|
||||||
|
|
|
@ -1581,12 +1581,13 @@ _rotate(ImagingObject* self, PyObject* args)
|
||||||
|
|
||||||
theta = fmod(theta, 360.0);
|
theta = fmod(theta, 360.0);
|
||||||
if (theta < 0.0)
|
if (theta < 0.0)
|
||||||
theta += 360;
|
theta += 360;
|
||||||
|
|
||||||
if (filter && imIn->type != IMAGING_TYPE_SPECIAL) {
|
if (filter && imIn->type != IMAGING_TYPE_SPECIAL) {
|
||||||
/* Rotate with resampling filter */
|
/* Rotate with resampling filter */
|
||||||
imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
|
imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
|
||||||
(void) ImagingRotate(imOut, imIn, theta, filter);
|
(void) ImagingRotate(imOut, imIn, theta, filter);
|
||||||
|
|
||||||
} else if ((theta == 90.0 || theta == 270.0)
|
} else if ((theta == 90.0 || theta == 270.0)
|
||||||
&& (expand || imIn->xsize == imIn->ysize)) {
|
&& (expand || imIn->xsize == imIn->ysize)) {
|
||||||
/* Use fast version */
|
/* Use fast version */
|
||||||
|
@ -1597,6 +1598,7 @@ _rotate(ImagingObject* self, PyObject* args)
|
||||||
else
|
else
|
||||||
(void) ImagingRotate270(imOut, imIn);
|
(void) ImagingRotate270(imOut, imIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
|
imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
|
||||||
if (imOut) {
|
if (imOut) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user