Rysuję kilka linii za pomocą ImageDraw.line (Python Imaging Library), ale wyglądają okropnie, ponieważ nie mogę znaleźć sposobu na ich wygładzenie. Jak mogę linie anty-alias w PIL? Jeśli PIL nie może tego zrobić, czy istnieje inna biblioteka manipulacji obrazami w języku Python?Rysowanie linii wygładzanej z biblioteką obrazowania Pythona
Odpowiedz
zapewnia ładniejszy rysunek niż PIL.
Wygląda ładnie, ale nie jest spakowany dla Ubuntu. Potrzebuję tego. – snostorm
Linie nadal wyglądają nierówno w agresywnym użyciu, korzystając z podstawowej metody losowania (punktów, pisaków). –
Czy jest to już dostępne w Python3? – DrMickeyLauer
To jest naprawdę szybko zhackowana funkcja do rysowania linii wygładzonej z PIL, którą napisałem po przeglądzie google dla tego samego problemu, widząc ten post i nie instalując agresora i będąc w napiętym terminie. Jest to implementacja algorytmu linii Xiaolin Wu. Mam nadzieję, że pomoże to każdemu googlować w tym samym celu !!
:)
"""Library to draw an antialiased line."""
# http://stackoverflow.com/questions/3122049/drawing-an-anti-aliased-line-with-thepython-imaging-library
# https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
import math
def plot(draw, img, x, y, c, col, steep, dash_interval):
"""Draws an antiliased pixel on a line."""
if steep:
x, y = y, x
if x < img.size[0] and y < img.size[1] and x >= 0 and y >= 0:
c = c * (float(col[3])/255.0)
p = img.getpixel((x, y))
x = int(x)
y = int(y)
if dash_interval:
d = dash_interval - 1
if (x/dash_interval) % d == 0 and (y/dash_interval) % d == 0:
return
draw.point((x, y), fill=(
int((p[0] * (1 - c)) + col[0] * c),
int((p[1] * (1 - c)) + col[1] * c),
int((p[2] * (1 - c)) + col[2] * c), 255))
def iround(x):
"""Rounds x to the nearest integer."""
return ipart(x + 0.5)
def ipart(x):
"""Floors x."""
return math.floor(x)
def fpart(x):
"""Returns the fractional part of x."""
return x - math.floor(x)
def rfpart(x):
"""Returns the 1 minus the fractional part of x."""
return 1 - fpart(x)
def draw_line_antialiased(draw, img, x1, y1, x2, y2, col, dash_interval=None):
"""Draw an antialised line in the PIL ImageDraw.
Implements the Xialon Wu antialiasing algorithm.
col - color
"""
dx = x2 - x1
if not dx:
draw.line((x1, y1, x2, y2), fill=col, width=1)
return
dy = y2 - y1
steep = abs(dx) < abs(dy)
if steep:
x1, y1 = y1, x1
x2, y2 = y2, x2
dx, dy = dy, dx
if x2 < x1:
x1, x2 = x2, x1
y1, y2 = y2, y1
gradient = float(dy)/float(dx)
# handle first endpoint
xend = round(x1)
yend = y1 + gradient * (xend - x1)
xgap = rfpart(x1 + 0.5)
xpxl1 = xend # this will be used in the main loop
ypxl1 = ipart(yend)
plot(draw, img, xpxl1, ypxl1, rfpart(yend) * xgap, col, steep,
dash_interval)
plot(draw, img, xpxl1, ypxl1 + 1, fpart(yend) * xgap, col, steep,
dash_interval)
intery = yend + gradient # first y-intersection for the main loop
# handle second endpoint
xend = round(x2)
yend = y2 + gradient * (xend - x2)
xgap = fpart(x2 + 0.5)
xpxl2 = xend # this will be used in the main loop
ypxl2 = ipart(yend)
plot(draw, img, xpxl2, ypxl2, rfpart(yend) * xgap, col, steep,
dash_interval)
plot(draw, img, xpxl2, ypxl2 + 1, fpart(yend) * xgap, col, steep,
dash_interval)
# main loop
for x in range(int(xpxl1 + 1), int(xpxl2)):
plot(draw, img, x, ipart(intery), rfpart(intery), col, steep,
dash_interval)
plot(draw, img, x, ipart(intery) + 1, fpart(intery), col, steep,
dash_interval)
intery = intery + gradient
Co to jest col? Co jest strome? Małe wyjaśnienie byłoby bardzo mile widziane. –
@RamenRecon, Ciekawi mnie również col i strome. Bazując na moim odczycie kodu, strome jest boolowskie dla tego, czy xdelta jest mniejsza od ydelta, a więc jeśli linia jest stroma, co prawdopodobnie wpływa na algorytm, ale jest używana tylko wewnętrznie przez funkcję drawLine i jej funkcję pomocnika wykresu, więc nie jest to nic użytkownik musi się martwić. Z drugiej strony użytkownik musi podać Col, i wydaje się być 4-krotnym kolorem RGBA (czerwony, gr, blu, alfa), który jest używany do określenia każdej wartości przezroczystości punktu alfa (tj. Efektu antyaliasingu). Ciekawy, aby spróbować i zobaczyć, jak szybko to jest ... –
Btw @toastie yours jest jedyną ręczną implementacją Pythona dla wygładzania ive seen wszędzie. Jestem zaskoczony, że twoja odpowiedź nie ma więcej upvotes, jestem pewien, że pomogło to grupie ludzi. +1 –
miałem podobny problem, moje wiersze miały ostre krawędzie, gdzie zmienia kierunek. Wyjaśniłem, w jaki sposób linie są rysowane w IOS i wymyśliłem ten kod. Nakłada zaokrąglone krawędzie linii na końcach linii i naprawdę czyści rzeczy. Niezupełnie anty-aliasing, ale jestem zupełnie nowy w PIL i tak trudno mi było znaleźć odpowiedź, pomyślałem, że się podzielę. Potrzebuje trochę skomplikowany i nie ma chyba lepszego sposobu, ale robi to, co trzeba :)
from PIL import Image
import ImageDraw
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class DrawLines:
def draw(self, points, color, imageName):
img = Image.new("RGBA", [1440,1080], (255,255,255,0))
draw = ImageDraw.Draw(img)
linePoints = []
for point in points:
draw.ellipse((point.x-7, point.y-7, point.x+7, point.y+7), fill=color)
linePoints.append(point.x)
linePoints.append(point.y)
draw.line(linePoints, fill=color, width=14)
img.save(imageName)
p1 = Point(100,200)
p2 = Point(190,250)
points = [p1,p2]
red = (255,0,0)
drawLines = DrawLines()
drawLines.draw(points, red, "C:\\test.png")
- 1. Instalowanie biblioteki obrazowania Pythona (PIL) na Ubuntu
- 2. Rysowanie linii na QWidget
- 3. Rysowanie ustalonego zestawu linii siatki z opencv
- 4. Rysowanie linii na iPhonie/iPadzie
- 5. Prześlij duży plik XML z biblioteką zapytań Pythona
- 6. Rysowanie zakrzywionych linii między punktami w ggmap
- 7. Rysowanie nieciągłych linii za pomocą d3
- 8. Rysowanie linii przerywanej za pomocą pliku fabric.js
- 9. rysowanie linii pomiędzy dwoma działek w matplotlib
- 10. Rysowanie wielu linii w D3.js
- 11. Rysowanie na żywo linii w D3.js
- 12. CGContext rysowanie linii: CGContextFillPath nie działa?
- 13. Rysowanie linii przerywanej za pomocą CGContextSetLineDash
- 14. Jak mogę wysłać ciągi danych do XBee z biblioteką Pythona?
- 15. Rysowanie linii między dwoma przeciągalnymi elementami div
- 16. Rysowanie linii między znacznikami w ulotce
- 17. rysowanie linii + przecięcia tej linii z siebie, a także wykryć CCSprites wewnątrz tej narysowanej linii
- 18. Rysowanie linii średniej na histogramie (matplotlib)
- 19. Rysowanie linii między parami w Pythonie
- 20. Rysowanie linii pionowych na wykresie spektrogramów matlab
- 21. Rysowanie linii od osi X do punktów
- 22. Rysowanie linii z Bezierpath przy użyciu obiektu CAShapeLayer
- 23. Przełamywanie linii Pythona na wiele linii?
- 24. subskrybowanie określonej linii z czytnika csv Pythona?
- 25. Rysowanie linii w OpenCV z flagami CV_AA nie generuje wygładzonej linii
- 26. Dystrybucja pakietu Pythona ze skompilowaną biblioteką współużytkowaną dynamiczną
- 27. Rysowanie fraktali z płomieniami
- 28. Rysowanie sfer z RadialGradientBrush
- 29. Rysowanie trójkątów z CUDA
- 30. Rysowanie pionowego zakończenia linii paska błędów w dotplot
Prawdopodobna odpowiedź: http://stackoverflow.com/questions/1828345/any-way-to-make-nice-antialiased- round-corners-for-images-in-python – unutbu
Cóż, przypuszczam, że jest to jedno rozwiązanie, jeśli jest wolne. – snostorm