About PIL.Image.Image.rotate method refinement
Jhonlier Suarez Molina <[email protected]>
| Newsgroups | gmane.comp.python.image |
|---|---|
| Message-ID | <[email protected]> |
When I was using PIL.Image.Image.rotate (expand=True) to make a sequence
of rotations to be joined later in a clip; but I found a trouble: my
object vibrates because the resulting vertex move around the expected
vertex. This is harmful for animations because you get undesirable
tremble. So I try the problem forcing the resulting surface size to be
odd in both dimentions, because the middle of these "odd" surfaces is
exactly a pixel, not a pixel given for rounding. Remember that the
middle of 1 2 3 4 5 6 7 8 9 clearly is 5, but the center of 1 2 3 4 is
"somewhere" beetwen 2 and 3.
I rewrite the "rotate" method:
def rotate(self, angle, resample=NEAREST, expand=0):
"Rotate image. Angle given as degrees counter-clockwise."
if expand:
import math
angle = -angle * math.pi / 180
matrix = [
math.cos(angle), math.sin(angle), 0.0,
-math.sin(angle), math.cos(angle), 0.0
]
def transform(x, y, (a, b, c, d, e, f)=matrix):
return a*x + b*y + c, d*x + e*y + f
# calculate output size
w, h = self.size
xx = []
yy = []
for x, y in ((0, 0), (w, 0), (w, h), (0, h)):
x, y = transform(x, y)
xx.append(x)
yy.append(y)
w = int(math.ceil(max(xx)) - math.floor(min(xx)))
h = int(math.ceil(max(yy)) - math.floor(min(yy)))
# adjust center
x, y = transform(w / 2.0, h / 2.0)
matrix[2] = self.size[0] / 2.0 - x
matrix[5] = self.size[1] / 2.0 - y
return self.transform((w, h), AFFINE, matrix)
if resample not in (NEAREST, BILINEAR, BICUBIC):
raise ValueError("unknown resampling filter")
self.load()
if self.mode in ("1", "P"):
resample = NEAREST
return self._new(self.im.rotate(angle, resample))
for this:
def rotate(self, angle, resample=NEAREST, expand=0):
"Rotate image. Angle given as degrees counter-clockwise."
if expand:
import math
angle = -angle * math.pi / 180
matrix = [
math.cos(angle), math.sin(angle), 0.0,
-math.sin(angle), math.cos(angle), 0.0
]
def transform(x, y, (a, b, c, d, e, f)=matrix):
return a*x + b*y + c, d*x + e*y + f
# calculate output size
w0, h0 = w, h = self.size
xx = []
yy = []
for x, y in ((0, 0), (w, 0), (w, h), (0, h)):
x, y = transform(x, y)
xx.append(x)
yy.append(y)
w = int(math.ceil(max(xx)) - math.floor(min(xx)))
if w & 1== 0:
w += 1
h = int(math.ceil(max(yy)) - math.floor(min(yy)))
if h & 1== 0:
h += 1
# adjust center
x, y = transform(w / 2.0, h / 2.0)
matrix[2] = w0 / 2.0 - x
matrix[5] = h0 / 2.0 - y
return self.transform((w, h), AFFINE, matrix)
if resample not in (NEAREST, BILINEAR, BICUBIC):
raise ValueError("unknown resampling filter")
self.load()
if self.mode in ("1", "P"):
resample = NEAREST
return self._new(self.im.rotate(angle, resample))
This really works I am using it now and no more Parkinson in my animations.
Saludos,
Jhonlier
--
__________ Información de ESET NOD32 Antivirus, versión de la base de firmas de virus 6059 (20110420) __________
ESET NOD32 Antivirus ha comprobado este mensaje.
http://www.eset.com
_______________________________________________
Image-SIG maillist - [email protected]
http://mail.python.org/mailman/listinfo/image-sig