Pregunta

Necesito cambiar el tamaño y recortar una imagen a un ancho y altura específicos. Pude construir un método que creará una miniatura cuadrada, pero no estoy seguro de cómo aplicar esto, cuando la miniatura deseada no es cuadrada.

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

Si hay una mejor manera de hacer esto, hágamelo saber. Cualquier ayuda sería muy apreciada.

Aquí hay un diagrama que explica el proceso deseado.crop_diagram

Gracias,

Kyle

¿Fue útil?

Solución

Tuve un problema similar (tu captura de pantalla fue muy útil). Esta es mi solución:

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()

Otros consejos

Puedes especificar ambos height y width parámetros resize - No cambiará la relación de aspecto (no puedes hacer eso con Gae's images módulo), pero asegurará que cada una de las dos dimensiones sea <= El valor correspondiente que especifique (de hecho, uno será exactamente igual al valor que especifique, el otro será <=).

No estoy seguro de por qué estás recortando primero y cambia de tamaño más tarde, parece que debes hacer las cosas al revés ... cambiar el tamaño para que gran parte de la imagen original "se ajuste" como sea factible, luego recorte para asegurarte para asegurarte Dimensión exacta resultante. (Por lo tanto, no usaría los valores originales de altura y ancho para el cambio de tamaño: los escalaría para que ninguna de las imágenes resultantes se "desperdicie" también conocida como "en blanco", si entiendo sus requisitos correctamente). Entonces, tal vez no entiendo exactamente lo que necesita: ¿podría proporcionar un ejemplo (URL a una imagen tal como se ve antes del procesamiento, cómo debería cuidar el procesamiento y los detalles de los parámetros que estaría pasando) ?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top