Frage

Ich muss die Größe ändern und ein Bild auf eine bestimmte Breite und Höhe aufnehmen. Ich konnte eine Methode erstellen, die eine quadratische Miniaturansicht erzeugt, aber ich bin mir nicht sicher, wie ich dies anwenden soll, wenn das gewünschte Miniaturbild nicht quadratisch ist.

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

Wenn es eine bessere Möglichkeit gibt, dies zu tun, lassen Sie es mich bitte wissen. Jede Hilfe wäre sehr geschätzt.

Hier ist ein Diagramm, das den gewünschten Prozess erklärt.crop_diagram

Vielen Dank,

Kyle

War es hilfreich?

Lösung

Ich hatte ein ähnliches Problem (Ihr Screenshot war sehr nützlich). Dies ist meine Lösung:

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

Andere Tipps

Sie können beide angeben height und width Parameter zu resize - Es wird das Seitenverhältnis nicht ändern (Sie können das mit GAEs nicht tun images Modul), aber es wird sicherstellen, dass jede der beiden Dimensionen ist <= Der entsprechende Wert, den Sie angeben (tatsächlich ist einer genau dem Wert, den Sie angeben, der andere ist <=).

Ich bin mir nicht sicher, warum Sie zuerst auftreten und später die Größe ändern - es scheint, als ob Sie die Dinge umgekehrt tun sollten ... die Größe der Größe so, dass so viel von dem Originalbild "wie möglich" passt, und dann zugreifen, um sicherzustellen, dass sie sichern exakt resultierende Dimension. (Sie würden also die ursprünglich bereitgestellten Werte der Höhe und Breite für die Größe nicht verwenden - Sie würden sie skalieren, damit keines der resultierenden Bild "verschwendet wird" "leer", wenn ich Ihre Anforderungen richtig verstehe). Vielleicht verstehe ich also nicht genau, was Sie benötigen - könnten Sie ein Beispiel geben (URLs für ein Bild, wie es vor der Verarbeitung aussieht, wie es sich um die Verarbeitung und Details der Parameter kümmern sollte, die Sie übergeben würden). ?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top