8

Tôi có một biểu tượng hình vuông và tôi cần phải round_corner nó, tìm kiếm một thời gian và nhận được mã follow "làm việc":Làm thế nào để round_corner một logo mà không có nền trắng (trong suốt?) Trên nó bằng cách sử dụng pil?

def round_corner_jpg(image, radius): 
    """generate round corner for image""" 
    mask = Image.new('RGB', image.size) 
    #mask = Image.new('RGB', (image.size[0] - radius, image.size[1] - radius)) 
    #mask = Image.new('L', image.size, 255) 
    draw = aggdraw.Draw(mask) 
    brush = aggdraw.Brush('black') 
    width, height = mask.size 
    draw.rectangle((0,0,width,height), aggdraw.Brush('white')) 
    #upper-left corner 
    draw.pieslice((0,0,radius*2, radius*2), 90, 180, None, brush) 
    #upper-right corner 
    draw.pieslice((width - radius*2, 0, width, radius*2), 0, 90, None, brush) 
    #bottom-left corner 
    draw.pieslice((0, height - radius * 2, radius*2, height),180, 270, None, brush) 
    #bottom-right corner 
    draw.pieslice((width - radius * 2, height - radius * 2, width, height), 270, 360, None, brush) 
    #center rectangle 
    draw.rectangle((radius, radius, width - radius, height - radius), brush) 
    #four edge rectangle 
    draw.rectangle((radius, 0, width - radius, radius), brush) 
    draw.rectangle((0, radius, radius, height-radius), brush) 
    draw.rectangle((radius, height-radius, width-radius, height), brush) 
    draw.rectangle((width-radius, radius, width, height-radius), brush) 
    draw.flush() 
    del draw 
    return ImageChops.add(mask, image) 

sau đó tôi lưu các đối tượng hình ảnh trở lại, tuy nhiên nó có nền trắng trong góc like this Làm cách nào để thoát khỏi nền trắng hoặc làm cho hình ảnh ẩn? Cảm ơn trước ~

EDIT: đây là mã bằng Fraxel, nhờ ~

def add_corners(im, rad): 
    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)) 
    im.putalpha(alpha) 
    return im 


if __name__ == '__main__': 
    im = Image.open('1.jpg') 
    im = add_corners(im, 100) 
    im.save('out.png')` 

Tôi rất sorry..I cần hình ảnh để có hình elip không hình chữ nhật, tức là. các công cụ viết ra khỏi pic, và @fraxel, tôi vẫn có thể thấy góc trắng trong ảnh mà bạn đã xử lý cho tôi

Trả lời

14

Trước hết, hãy chắc chắn bạn đang lưu hình ảnh của bạn trong một định dạng hỗ trợ minh bạch. PNG, JPG không ... Dưới đây là một số mã khá đẹp sẽ thêm góc trong suốt. Nó hoạt động như thế này:

  1. Vẽ một vòng tròn với bán kính, rad, sử dụng draw.ellipse()
  2. Tạo một hình ảnh cho alpha kênh kích thước giống như hình ảnh của bạn
  3. Chop vòng tròn của chúng tôi thành bốn mảnh (các góc tròn) và đặt chúng vào các góc chính xác của hình ảnh alpha
  4. Đặt kênh alpha vào hình ảnh của bạn bằng cách sử dụng putalpha()
  5. Lưu dưới dạng png, do đó giữ được độ trong suốt.

Đây là mã:

import Image, ImageDraw 

def add_corners(im, rad): 
    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, 255) 
    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)) 
    im.putalpha(alpha) 
    return im 

im = Image.open('tiger.jpg') 
im = add_corners(im, 100) 
im.save('tiger.png') 

dụ cong cạnh hổ:

enter image description here

đây là hình ảnh của bạn, xử lý với mã này, cho góc trong suốt:

enter image description here

+0

cảm ơn, nhưng nó vẫn có góc trắng trên nền. Hãy xem [link] này (http://www.flickr.com/photos/[email protected] N03/7485468218/in/photostream) để xem vấn đề, và tôi cần góc màu hồng vô hình, trong trường hợp của bạn góc trắng (U không thể nhìn thấy nó ở đây vì nó trắng, cùng màu như trang web) .. Hy vọng bạn hiểu ý tôi là gì – bdictator

+0

@bdictator - vui lòng đăng mã đầy đủ của bạn. và bạn đang sử dụng mã của tôi và tiết kiệm như một png? – fraxel

+0

có, tôi đang sử dụng mã của bạn, hãy xem mã được thêm vào của tôi – bdictator

0

Bạn đã thử một số thứ như image.putalpha(mask) để thay thế kênh alpha của hình ảnh bằng mặt nạ? Điều này có vẻ như nó sẽ làm những gì bạn muốn. mask có thể phải ở chế độ 'L' để hoạt động chính xác và image nên probaby là 'RGBA', nhưng có thể được tự động chuyển đổi cho bạn.

Câu trả lời đầu ở đây đưa ra một số ví dụ điển hình: How do I generate circular thumbnails with PIL?

hình ảnh mặt nạ của bạn có vẻ tốt đẹp, nhưng tôi nghĩ rằng bạn muốn trao đổi 'trắng' và 'đen', vì vậy bạn có một hình chữ nhật tròn trắng chính xác hình dạng bạn muốn hình ảnh cuối cùng của bạn, trên nền đen. Có thể bạn cũng sẽ cần sử dụng chế độ 'L' (greyscale).

Khi bạn có hình ảnh này, bạn có thể thay thế return ImageChops.add(mask, image) bằng image.putalpha(mask); return image và điều này sẽ làm cho hình ảnh trong suốt chỉ trong các khu vực màu đen của mặt nạ.

Bạn có thể cần phải chuyển đổi hình ảnh đầu tiên với image.convert('RGBA') nhưng tôi nghĩ rằng điều này là không cần thiết trong các phiên bản sau của PIL, nó sẽ tự động.

Cái gì như: (xin lỗi không thể kiểm tra này ngay bây giờ)

 
def round_corner_jpg(image, radius): 
    """generate round corner for image""" 
    mask = Image.new('L', image.size) # filled with black by default 
    draw = aggdraw.Draw(mask) 
    brush = aggdraw.Brush('white') 
    width, height = mask.size 
    #upper-left corner 
    draw.pieslice((0,0,radius*2, radius*2), 90, 180, None, brush) 
    #upper-right corner 
    draw.pieslice((width - radius*2, 0, width, radius*2), 0, 90, None, brush) 
    #bottom-left corner 
    draw.pieslice((0, height - radius * 2, radius*2, height),180, 270, None, brush) 
    #bottom-right corner 
    draw.pieslice((width - radius * 2, height - radius * 2, width, height), 270, 360, None, brush) 
    #center rectangle 
    draw.rectangle((radius, radius, width - radius, height - radius), brush) 
    #four edge rectangle 
    draw.rectangle((radius, 0, width - radius, radius), brush) 
    draw.rectangle((0, radius, radius, height-radius), brush) 
    draw.rectangle((radius, height-radius, width-radius, height), brush) 
    draw.rectangle((width-radius, radius, width, height-radius), brush) 
    draw.flush() 
    image = image.convert('RGBA') 
    image.putalpha(mask) 
    return image 
+0

, Vui lòng xem liên kết tôi đã thêm để xem sự cố. Tôi không nghĩ liên kết U đã cung cấp là những gì tôi đang tìm kiếm và tôi không chắc chắn những gì U đã nói về nội dung alpha .. – bdictator

+0

@bdictator kênh "alpha" là một phần của hình ảnh chứa thông tin minh bạch. 'image.putalpha (mask)' chỉ thay thế thông tin minh bạch bằng ảnh mặt nạ, trong đó màu mặt nạ trắng có nghĩa là độ mờ đục hoàn toàn (không có độ trong suốt - ảnh gốc), và màu đen có nghĩa là toàn trong suốt (hoàn toàn nhìn thấy). Tôi sẽ thử cập nhật câu trả lời để thêm một số chi tiết. – mesilliac

+0

Cảm ơn rất nhiều, nhưng có vẻ như cùng với công cụ màu trắng trên góc backgroud – bdictator