project.py
project.py

Reputation: 103

How to lower transparency to line in Pillow?

How to lower opacity to line? I would like to lower opacity to one of line in example bellow.

from PIL import Image, ImageDraw

img = Image.new('RGB', (100, 100), (255, 255, 255))
draw = ImageDraw.Draw(img)
draw.line((100, 30, 0, 30), (0, 0, 0), 20)
draw.line((100, 70, 0, 70), (0, 0, 0), 20)
img.show()

I have seen in one example they created opacity like this...

TRANSPARENCY = .25  # Degree of transparency, 0-100%
OPACITY = int(255 * TRANSPARENCY)

But don't know how to apply to one of lines. Any ideas?

EDIT

I made some changes (based on answer of @Pedro Maia), it still doesn't work, just changes a color, it doesn't lower opacity to see background color.

from PIL import Image, ImageDraw

img = Image.new('RGBA', (500, 500), (255, 255, 255))
draw = ImageDraw.Draw(img)
TRANSPARENCY = .25  # Degree of transparency, 0-100%
draw.line((200, 0, 200, 600),(255, 0, 0), 60)
draw.line((500, 100, 0, 100), (0, 0, 0, int(255 * TRANSPARENCY)), 60)
draw.line((500, 400, 0, 400),(0, 0, 0), 60)
img

And I have to convert it to RGB to export it as 'jpg'

Upvotes: 0

Views: 1403

Answers (2)

martineau
martineau

Reputation: 123463

You would have to do something like this, which is similar to how the example code works, to do what (I think) you want to. I changed the code you added to your question in the EDIT slightly so it better demonstrates that lines of different amounts of transparency can be drawn.

from PIL import Image, ImageDraw

RED = (255, 0, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

# Calculate alpha given a 0-100% opacity value.
opacity = lambda transparency: (int(255 * (transparency/100.)),)  # Returns a monuple.

def draw_transp_line(image, xy, color, width=1, joint=None):
    """ Draw line with transparent color on the specified image. """
    if len(color) < 4:  # Missing alpha?
        color += opacity(100)  # Opaque since alpha wasn't specified.

    # Make an overlay image the same size as the specified image, initialized to
    # a fully transparent (0% opaque) version of the line color, then draw a
    # semi-transparent line on it.
    overlay = Image.new('RGBA', image.size, color[:3]+opacity(0))
    draw = ImageDraw.Draw(overlay)  # Create a context for drawing things on it.
    draw.line(xy, color, width, joint)
    # Alpha composite the overlay image onto the original.
    image.alpha_composite(overlay)


# Create opaque white RGBA background image.
img = Image.new('RGBA', (500, 500), (255, 255, 255)+opacity(100))

draw_transp_line(img, ((200, 0), (200, 600)), RED+opacity(100), 60)
draw_transp_line(img, ((500, 100), (0, 100)), BLACK+opacity(25), 60)
draw_transp_line(img, ((150, 50), (600, 400)), BLACK+opacity(50), 60)

img = img.convert("RGB") # Remove alpha for saving in jpg format.
img.save('transparent_lines.jpg')
img.show()

JPG image created:

resulting JPG image

Upvotes: 2

Pedro Maia
Pedro Maia

Reputation: 2722

With draw.line you can pass as argument RGB or RGBA just pass the value of the transparency:

draw.line((100, 30, 0, 30), (0, 0, 0, int(255 * TRANSPARENCY)), 20)

Also when creating the image set it as RGBA:

img = Image.new('RGBA', (100, 100), (255, 255, 255))

Upvotes: 0

Related Questions