App -Engine, die zu einer bestimmten Breite und Höhe schneidet
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.
Vielen Dank,
Kyle
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). ?