Question

J'ai besoin de redimensionner et de recadrer une image sur une largeur et une hauteur spécifiques. J'ai pu construire une méthode qui créera une miniature carrée, mais je ne suis pas sûr de l'appliquer, lorsque la miniature souhaitée n'est pas carrée.

def rescale(data, width, height):
"""Rescale the given image, optionally cropping it to make sure the result image has the specified width and height."""
from google.appengine.api import images

new_width = width
new_height = height

img = images.Image(data)

org_width, org_height = img.width, img.height

# We must determine if the image is portrait or landscape
# Landscape
if org_width > org_height:
    # With the Landscape image we want the crop to be centered. We must find the
    # height to width ratio of the image and Convert the denominater to a float
    # so that ratio will be a decemal point. The ratio is the percentage of the image
    # that will remain.
    ratio = org_height / float(org_width)
    # To find the percentage of the image that will be removed we subtract the ratio
    # from 1 By dividing this number by 2 we find the percentage that should be
    # removed from each side this is also our left_x coordinate
    left_x = (1- ratio) / 2
    # By subtract the left_x from 1 we find the right_x coordinate
    right_x = 1 - left_x
    # crop(image_data, left_x, top_y, right_x, bottom_y), output_encoding=images.PNG)
    img.crop(left_x, 0.0, right_x, 1.0)
    # resize(image_data, width=0, height=0, output_encoding=images.PNG)
    img.resize(height=height)
# Portrait
elif org_width < org_height:
    ratio = org_width / float(org_height)
    # crop(image_data, left_x, top_y, right_x, bottom_y), output_encoding=images.PNG)
    img.crop(0.0, 0.0, 1.0, ratio)
    # resize(image_data, width=0, height=0, output_encoding=images.PNG)
    img.resize(width=witdh)

thumbnail = img.execute_transforms()
return thumbnail

S'il y a une meilleure façon de le faire, faites-le moi savoir. Toute aide serait grandement appréciée.

Voici un diagramme expliquant le processus souhaité.crop_diagram

Merci,

Kyle

Était-ce utile?

La solution

J'ai eu un problème similaire (votre capture d'écran était très utile). Ceci est ma solution:

def rescale(img_data, width, height, halign='middle', valign='middle'):
  """Resize then optionally crop a given image.

  Attributes:
    img_data: The image data
    width: The desired width
    height: The desired height
    halign: Acts like photoshop's 'Canvas Size' function, horizontally
            aligning the crop to left, middle or right
    valign: Verticallly aligns the crop to top, middle or bottom

  """
  image = images.Image(img_data)

  desired_wh_ratio = float(width) / float(height)
  wh_ratio = float(image.width) / float(image.height)

  if desired_wh_ratio > wh_ratio:
    # resize to width, then crop to height
    image.resize(width=width)
    image.execute_transforms()
    trim_y = (float(image.height - height) / 2) / image.height
    if valign == 'top':
      image.crop(0.0, 0.0, 1.0, 1 - (2 * trim_y))
    elif valign == 'bottom':
      image.crop(0.0, (2 * trim_y), 1.0, 1.0)
    else:
      image.crop(0.0, trim_y, 1.0, 1 - trim_y)
  else:
    # resize to height, then crop to width
    image.resize(height=height)
    image.execute_transforms()
    trim_x = (float(image.width - width) / 2) / image.width
    if halign == 'left':
      image.crop(0.0, 0.0, 1 - (2 * trim_x), 1.0)
    elif halign == 'right':
      image.crop((2 * trim_x), 0.0, 1.0, 1.0)
    else:
      image.crop(trim_x, 0.0, 1 - trim_x, 1.0)

  return image.execute_transforms()

Autres conseils

Vous pouvez spécifier les deux height et width paramètres de resize - cela ne changera pas le rapport d'aspect (vous ne pouvez pas le faire avec GAE images module), mais il garantira que chacune des deux dimensions est <= La valeur correspondante que vous spécifiez (en fait, l'une sera exactement égale à la valeur que vous spécifiez, l'autre sera <=).

Je ne sais pas pourquoi vous recadrorez d'abord et redimensionner plus tard - il semble que vous devriez faire les choses l'inverse ... redimensionner pour que la plupart de l'image d'origine "s'adapte" comme c'est possible, puis recadré pour s'assurer Dimension exacte résultant. (Donc, vous n'utiliseriez pas les valeurs d'origine fournies par la hauteur et la largeur pour le redimensionnement - vous les réduisez afin qu'aucune de l'image résultante ne soit "gaspillée" AKA "vide", si je comprends correctement vos exigences). Alors peut-être que je ne comprends pas exactement ce dont vous avez besoin - pourriez-vous fournir un exemple (URL à une image telle qu'elle ressemble avant le traitement, à la façon dont elle devrait s'occuper du traitement et des détails des paramètres que vous passez) ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top