def portrait(self, image=None, scale=(2.6, 3.0), xy_ratio=0.875):
"""Return a copy of the coordinates converted to the portrait scale.
A xy ratio can be forced, for example, to force a 4:5 image, ie
proprtionnal to width=4 and height=5, set xy_ratio to 0.8.
:param image: (sppasImage) The original image.
:param scale: (float or tuple) Scale factor.
:param xy_ratio: (float or None) Force a xy ratio. Default is 14:16.
:return: (sppasCoords)
>>> # Scale the coords to fit a default portrait size
>>> coordinates.portrait(image)
>>> # Scale the coords to be larger than a portrait, like a selfie
>>> coordinates.portrait(image, scale=4.8)
>>> # Scale coords to a custom portrait size
>>> coordinates.portrait(image, scale=(2.6, 3.4))
"""
coord = self.copy()
if isinstance(scale, (tuple, list)):
shift_x = coord.scale_x(scale[0])
shift_y = coord.scale_y(scale[1])
elif isinstance(scale, (float, int)):
shift_x, shift_y = coord.scale(scale)
else:
raise sppasTypeError(type(scale), 'int, float, tuple, list')
if xy_ratio is not None and coord.w * coord.h > 0:
current_ratio = float(coord.w) / float(coord.h)
if current_ratio > xy_ratio:
sy = coord.scale_y(current_ratio / xy_ratio)
shift_y += sy
elif current_ratio < xy_ratio:
sx = coord.scale_x(xy_ratio / current_ratio)
shift_x += sx
shift_y = int(float(shift_y) * 0.5)
if image is None:
coord.shift(shift_x, shift_y)
else:
try:
coord.shift(shift_x, 0, image)
shifted_x = True
except:
shifted_x = False
try:
coord.shift(0, shift_y, image)
shifted_y = True
except:
shifted_y = False
w, h = image.size()
if coord.x + coord.w > w or shifted_x is False:
coord.x = max(0, w - coord.w)
if coord.y + coord.h > h or shifted_y is False:
coord.y = max(0, h - coord.h)
return coord