52 Stimmen

Wie erzeuge ich mit PIL runde Vorschaubilder?

Wie erzeuge ich runde Bildminiaturen mit PIL? Der Raum außerhalb des Kreises sollte transparent sein.

Schnipsel wären sehr willkommen, vielen Dank im Voraus.

100voto

Nadia Alramli Punkte 105256

Am einfachsten geht das mit Hilfe von Masken. Erstellen Sie eine schwarz-weiße Maske mit einer beliebigen Form. Und verwenden Sie putalpha um diese Form als Alphaebene anzulegen:

from PIL import Image, ImageOps

mask = Image.open('mask.png').convert('L')
im = Image.open('image.png')

output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.putalpha(mask)

output.save('output.png')

Hier ist die Maske, die ich verwendet habe:

alt text


Wenn Sie möchten, dass die Größe der Miniaturbilder variabel ist, können Sie ImageDraw und zeichnen Sie die Maske:

from PIL import Image, ImageOps, ImageDraw

size = (128, 128)
mask = Image.new('L', size, 0)
draw = ImageDraw.Draw(mask) 
draw.ellipse((0, 0) + size, fill=255)

im = Image.open('image.jpg')

output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.putalpha(mask)

output.save('output.png')

Wenn Sie die Ausgabe im GIF-Format wünschen, müssen Sie die Einfügefunktion anstelle von putalpha :

from PIL import Image, ImageOps, ImageDraw

size = (128, 128)
mask = Image.new('L', size, 255)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + size, fill=0)

im = Image.open('image.jpg')

output = ImageOps.fit(im, mask.size, centering=(0.5, 0.5))
output.paste(0, mask=mask)
output.convert('P', palette=Image.ADAPTIVE)

output.save('output.gif', transparency=0)

Beachten Sie, dass ich die folgenden Änderungen vorgenommen habe:

  • Die Maske ist nun invertiert. Das Weiß wurde durch Schwarz ersetzt und umgekehrt.
  • Ich konvertiere in 'P' mit einer 'adaptiven' Palette. Andernfalls wird PIL nur websichere Farben verwenden und das Ergebnis wird schlecht aussehen.
  • Ich füge dem Bild eine Transparenzinformation hinzu.

Bitte beachten Sie : Bei diesem Ansatz gibt es ein großes Problem. Wenn das GIF-Bild schwarze Teile enthielt, werden alle diese Teile auch transparent. Sie können dieses Problem umgehen, indem Sie eine andere Farbe für die Transparenz wählen. Ich würde Ihnen dringend empfehlen, dafür das PNG-Format zu verwenden. Aber wenn Sie das nicht können, ist das das Beste, was Sie tun können.

0 Stimmen

Großartig! Und wie wäre es mit der Ausgabe von gif anstelle von png? Ich vermute, dass gif nicht mit Alpha umgehen kann, oder?

0 Stimmen

Gif unterstützt keine Alphakanal-Transparenz. Es unterstützt nur die Einstellung einer Farbe als transparent. Ich habe jedoch die notwendige Anpassung vorgenommen, um das Ergebnis in Gif auszugeben.

0 Stimmen

Große Antwort. während ich diese Technik leicht auf gespeicherte Bilder anwenden kann, lief ich in ein Problem der Anwendung der Maske innerhalb Python. jede Chance, die Sie einen Blick auf diese Frage nehmen könnte: stackoverflow.com/questions/20150552/

43voto

DRC Punkte 4678

Ich möchte der bereits akzeptierten Antwort eine Lösung für die Antialias-Bearbeitung des resultierenden Kreises hinzufügen. Der Trick besteht darin, eine größere Maske zu erstellen und sie dann mit einem ANTIALIAS-Filter zu verkleinern: Hier ist der Code

from PIL import Image, ImageOps, ImageDraw

im = Image.open('image.jpg')
bigsize = (im.size[0] * 3, im.size[1] * 3)
mask = Image.new('L', bigsize, 0)
draw = ImageDraw.Draw(mask) 
draw.ellipse((0, 0) + bigsize, fill=255)
mask = mask.resize(im.size, Image.ANTIALIAS)
im.putalpha(mask)

Dies führt meiner Meinung nach zu einem weitaus besseren Ergebnis.

3 Stimmen

Kumpel, die ANTIALIAS haben einen großen Unterschied gemacht! Danke! =D

1 Stimmen

Das hat bei mir sehr gut funktioniert. Es ist nicht nötig, eine Maske zu entwerfen.

2 Stimmen

Der beste Tipp überhaupt!!

3voto

xjcl Punkte 8813

Geringfügige Änderung an @DRCs Lösung, um auch die Bilder, die bereits Transparenz aufweisen . Er setzt den Alphakanal auf 0 (unsichtbar) außerhalb des Kreises und auf 255 innerhalb (undurchsichtig), also verwende ich darker die die min der Maske und des ursprünglichen Alphakanals (der irgendwo zwischen 0-255 liegen kann) :-)

from PIL import Image, ImageChops, ImageDraw

def crop_to_circle(im):
    bigsize = (im.size[0] * 3, im.size[1] * 3)
    mask = Image.new('L', bigsize, 0)
    ImageDraw.Draw(mask).ellipse((0, 0) + bigsize, fill=255)
    mask = mask.resize(im.size, Image.ANTIALIAS)
    mask = ImageChops.darker(mask, im.split()[-1])
    im.putalpha(mask)

im = Image.open('0.png').convert('RGBA')
crop_to_circle(im)
im.save('cropped.png')

0 Stimmen

Oder verwenden Sie einfach Image.paste() und eine Maske hinzufügen

1voto

andsa Punkte 171

Ich danke Ihnen vielmals. Ich war stundenlang auf der Suche, und Ihre Idee hat den Trick.

Zusammen mit diesem anderen Skript von dort. PIL runde Kanten und Rand hinzufügen Bei mir funktioniert es perfekt.

from PIL import Image
from PIL import ImageDraw, ImageChops

def add_corners( im, rad=100):
    circle = Image.new('L', (rad * 2, rad * 2), 0)
    draw = ImageDraw.Draw(circle)
    draw.ellipse((0, 0, rad * 2, rad * 2), fill=255)
    alpha = Image.new('L', im.size, "white")
    w, h = im.size
    alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
    alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
    alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
    alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))

    alpha = ImageChops.darker(alpha, im.split()[-1])

    im.putalpha(alpha)
    return im

im = Image.open ('AceOfSpades.png').convert('RGBA')

im = add_corners (im, 24)

im.show()
im.save("perfect.png")

Benennen Sie dieses Bild zu Testzwecken AceOfSpades.png

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X