[Image-SIG] About PIL.Image.Image.rotate method refinement
Jhonlier Suarez Molina
jhonlier12017 at hlg.jovenclub.cu
Thu Apr 21 03:48:07 CEST 2011
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/image-sig/attachments/20110420/c27cff2b/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: LaComputadoradelafamiliacubana.jpg
Type: image/jpeg
Size: 5339 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/image-sig/attachments/20110420/c27cff2b/attachment.jpg>
More information about the Image-SIG
mailing list