2010-06-25 21 views
6

Python Görüntüleme Kitaplığı'nın ImageDraw.line() yöntemiyle bir dizi çizgi çiziyorum, ancak bunlar, anti-alias'ları kullanmanın bir yolunu bulamadığım için çok şaşırıyorlar. PIL'de satırları nasıl anti-alias yapabilirim? PIL yapamazsa, başka bir Python görüntü işleme kitaplığı olabilir mi?Python Görüntüleme Kitaplığı ile kenar yumuşatılmış bir çizgi çizme

+0

Olası cevap :) gerekenleri yapar: http://stackoverflow.com/questions/1828345/any-way-to-make-nice-antialiased- python – unutbu

+0

için yuvarlak köşeler-yuvarlak, sanırım, yavaş bir tane, bu bir çözümdür. – snostorm

cevap

3

aggdraw PIL'den daha güzel çizim sağlar.

+0

Güzel görünüyor, ama Ubuntu için paketlenmedi. Buna ihtiyacım var. – snostorm

+0

Hatlar hala temel çizim (nokta, kalem) yöntemini kullanarak agdrawda dalgalı görünebilir. –

+0

Bu Python3 için mevcut mu? – DrMickeyLauer

11

Bu, aynı sorun için googling ettikten sonra yazdığım PIL ile kenar yumuşatılmış bir çizgi çizmek, bu gönderiyi görmek ve agdraw ve sıkı bir son tarihte yüklenememesi için çok hızlı bir şekilde birbirine kenetlenmiş bir işlevdir. Xiaolin Wu'nun çizgi algoritmasının bir uygulaması. Umarım aynı şey için googling herkese yardımcı olur!

:)

"""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 
+0

col nedir? Dik nedir? Küçük bir açıklama büyük ölçüde takdir edilecektir. –

+0

@RamenRecon, ben de col ve dik dikenliydi. Kodun okunmasına dayanarak, dik xdelta'nın ydelta'dan daha az olup olmadığına dair bir boole olup, bu durumda çizgi muhtemelen algoritmayı etkileyecek şekilde dik ise ancak drawLine fonksiyonu ve çizim yardımcı fonksiyonu tarafından dahili olarak kullanılır. Kullanıcı endişelenmeli. Diğer taraftan Col, kullanıcı tarafından verilmeli ve her bir nokta alfa transparanlık değerine (yani antialiasing etkisine) karar vermek için kullanılan 4-tuple RGBA rengi (kırmızı, gr, blu, alfa) gibi görünmektedir. Bunu denemek ve ne kadar hızlı olduğunu görmek için meraklı ... –

+1

Btw @toastie yours her yerde görülen antialiasing için tek manuel Python uygulamasıdır. Cevabın daha fazla vardiya olmadığına şaşırdım, ama bir grup insana yardım ettiğinden eminim. +1 –

2

Yolu tarif değişen nerede Çizgilerim pürüzlerini vardı, buna benzer bir sorun vardı. IOS'ta çizgilerin nasıl çizildiğine dair bir ipucu aldım ve bu kodla geldi. Hatların uçlarına yuvarlak hat kapaklarını koyar ve gerçekten şeyleri temizler. Tam olarak anti-aliasing değil, PIL için tamamen yeni ve paylaşacağımı düşündüğüm bir cevap bulmakta zorlandım. biraz oynanması gerekiyor ve orada daha iyi bir yolu muhtemelen ama ben


    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") 
İlgili konular