2013-05-20 2 views
10

Wie kann ich ein Bild in der Mitte zuschneiden? Weil ich weiß, dass die Box ein 4-Tupel ist, das die linke, obere, rechte und untere Pixelkoordinate definiert, aber ich weiß nicht, wie ich diese Koordinaten bekommen soll, damit sie in der Mitte schneidet.Beschneiden Sie ein Bild in der Mitte mit PIL

+0

Sie die Größe des Bildes kennen und die Größe des kleineren Bildes, das Sie erhalten möchten, ich annehmen? Hast du etwas zu zeigen, wo du es versucht hast? –

Antwort

29

Angenommen, Sie kennen die Größe, die Sie möchten (new_width X new_height) zuzuschneiden:

import Image 
im = Image.open(<your image>) 
width, height = im.size # Get dimensions 

left = (width - new_width)/2 
top = (height - new_height)/2 
right = (width + new_width)/2 
bottom = (height + new_height)/2 

im.crop((left, top, right, bottom)) 

Dies wird brechen, wenn Sie ein kleines Bild größer zu beschneiden versuchen, aber ich werde Sie davon ausgehen, gewonnen versuch das nicht (oder dass du diesen Fall erfassen kannst und das Bild nicht zuschneiden kannst).

+0

Okay, endlich hat es funktioniert! Tausend Dank. – user2401069

+0

Kleine Korrektur, Ernte dauert ein Array. im.crop ((links, oben, rechts, unten)) – freakTheMighty

+0

Nitpick: Sie meinen eine Sequenz, kein Array. :) – EOL

3

Ein mögliches Problem mit der vorgeschlagenen Lösung ist in dem Fall, dass es einen ungeraden Unterschied zwischen der gewünschten Größe und der alten Größe gibt. Sie können kein halbes Pixel auf jeder Seite haben. Man muss eine Seite wählen, auf die man ein zusätzliches Pixel setzen kann.

Wenn es ein ungeradeer Unterschied für die horizontale ist unter dem Code wird das zusätzliche Pixel nach rechts, und wenn es auf den vertikalen den zusätzlichen Pixeln und ungeradeen Unterschied ist, geht nach unten.

import numpy as np 

def centeredCrop(img, new_height, new_width): 

    width = np.size(img,1) 
    height = np.size(img,0) 

    left = np.ceil((width - new_width)/2.) 
    top = np.ceil((height - new_height)/2.) 
    right = np.floor((width + new_width)/2.) 
    bottom = np.floor((height + new_height)/2.) 
    cImg = img[top:bottom, left:right] 
    return cImg 
+3

Rundung ist falsch, das Ergebnisbild wird nicht immer die erforderlichen Dimensionen haben. Die richtige Formel ist 'right = width - floor ((width - new_width)/2)' –

2

Dies ist die Funktion, die ich suche:

from PIL import Image 
im = Image.open("test.jpg") 

crop_rectangle = (50, 50, 200, 200) 
cropped_im = im.crop(crop_rectangle) 

cropped_im.show() 

Entnommen another answer