Search code examples
pythoncolorspython-imaging-librarydiagonal

generating equal diagonal lines in PIL


What I'm trying to do is generate equal diagonal lines in PIL. What I'm doing is first making a horizontal equally square and then rotating it 45 degrees. But when I'm rotating it the lines aren't big enough, there shouldn't be any black and still be equal. It also should work with more colors

code:

import random

im = Image.new('RGB', (1000, 1000), (255, 255, 255))
draw = ImageDraw.Draw(im)
colors = [(255,0,255), (0,0,255)]
random.shuffle(colors)
length = len(colors)
amount = 1000 / length
x1 = 0
y1 = 0
x2 = 1000
y2 = 0
for color in colors:
    shape = [(x1, y1 + amount // 2), (x2, y2 + amount // 2)]
    draw.line(shape, fill=color, width=int(amount))
    y1 += amount
    y2 += amount

im.save("pre_diagonal.png")
colorimage = Image.open('pre_diagonal.png')
out = colorimage.rotate

enter image description here

enter image description here


Solution

  • You can do it by first generating an image of vertical lines like I showed you in my answer to your other question, rotating that by 45°, and then cropping it. To avoid having areas of black, you need to generate an initial image that is large enough for the cropping.

    In this case that's simply a square image with sides the length of the hypotenuse (diagonal) of the final target image's size.

    hypotenuse

    i.e. formula

    Graphically, here's what I mean:

    uncropped image

    At any rate, here's the code that does it:

    from math import hypot
    from PIL import Image, ImageDraw
    import random
    
    IMG_WIDTH, IMG_HEIGHT = 1000, 1000
    DIAG = round(hypot(IMG_WIDTH, IMG_HEIGHT))
    
    img = Image.new('RGB', (DIAG, DIAG), (255, 255, 255))
    draw = ImageDraw.Draw(img)
    colors = [(255,0,255), (0,0,255)]
    random.shuffle(colors)
    
    length = len(colors)  # Number of lines.
    line_width = DIAG / length  # Width of each.
    difx = line_width / 2
    x1, y1 = difx, 0
    x2, y2 = difx, DIAG
    
    for color in colors:
        endpoints = (x1, y1), (x2, y2)
        draw.line(endpoints, fill=color, width=round(line_width))
        x1 += line_width
        x2 += line_width
    
    img = img.rotate(-45, resample=Image.Resampling.BICUBIC)
    difx, dify = (DIAG-IMG_WIDTH) // 2, (DIAG-IMG_HEIGHT) // 2
    img = img.crop((difx, dify, difx+IMG_WIDTH, dify+IMG_HEIGHT))
    img.save('diagonal.png')
    #img.show()
    

    Here's the resulting image:

    diagonal image