Perfect crops.

Also eliminate redundant get_cropspec code.
Also eliminate redundant apply_rotation call.
This commit is contained in:
Conrad Hughes 2020-11-03 13:01:29 +00:00
parent 4acc9e6399
commit c7ff1046b8

View file

@ -69,23 +69,8 @@ def get_cropspec(image, corners, rotation):
t, l, r, b = corners
w = r - l
h = b - t
# The coordinates passed to jpegtran are interpreted post-rotation.
# Non-whole blocks are already imperfectly rotated by being left on the
# side, so we need to subtract them
if image.format == "JPEG":
round_x, round_y = image_round(image)
orig_w, orig_h = image.size
if rotation in (8, 6):
orig_w, orig_h = orig_h, orig_w
round_x, round_y = round_y, round_x
if rotation in (3, 8):
t -= orig_h % round_y
if rotation in (3, 6):
l -= orig_w % round_x
assert t >= 0, "t < 0 should be handled in fix(): {}".format(t)
assert l >= 0, "l < 0 should be handled in fix(): {}".format(l)
# Technically this should produce perfect crops, but jpegtran is broken
# and so mistakenly rounds out fractional crops on flipped images. Sigh.
return "%dx%d+%d+%d" % (w, h, l, t)
@ -209,7 +194,6 @@ class DragManagerBase(object):
def image_or_rotation_changed(self):
self._image = image = self.apply_rotation(self._orig_image)
self.apply_rotation(image)
self.top, self.bottom = self.fix(0, self.h, self.h, self.round_y, self.rotation in (3, 8))
self.left, self.right = self.fix(0, self.w, self.w, self.round_x, self.rotation in (3, 6))
blurred = image.copy()
@ -227,18 +211,11 @@ class DragManagerBase(object):
r: rounding size
reverse: True to treat the upper bound as the origin
"""
if reverse:
offset = lim % r
else:
offset = 0
a, b = sorted((int(a), int(b)))
a = ((a - offset) // r) * r + offset
b = ((b - offset + r - 1) // r) * r + offset
# jpegtran handles non-whole blocks by leaving them on the edge of the
# image, away from the rotated position of their old neighbors.
# Keeping them isn't useful, so clamp them off.
a = clamp(a, offset if reverse else 0, lim)
b = clamp(b, offset if reverse else 0, lim)
if reverse:
a = lim - ((((lim - a) + r - 1) // r) * r)
else:
a = (a // r) * r
return a, b
def get_corners(self):