python - 如何在图像周围添加圆形边框?
解决方案
我喜欢用 SVG 绘制圆角矩形来进行更改——尤其是因为有人认为我总是使用 ImageMagick ;-)
#!/usr/bin/env python3
from PIL import ImageOps, Image
from cairosvg import svg2png
from io import BytesIO
def frame(im, thickness=5):
# Get input image width and height, and calculate output width and height
iw, ih = im.size
ow, oh = iw+2*thickness, ih+2*thickness
# Draw outer black rounded rect into memory as PNG
outer = f'<svg width="{ow}" height="{oh}" style="background-color:none"><rect rx="20" ry="20" width="{ow}" height="{oh}" fill="black"/></svg>'
png = svg2png(bytestring=outer)
outer = Image.open(BytesIO(png))
# Draw inner white rounded rect, offset by thickness into memory as PNG
inner = f'<svg width="{ow}" height="{oh}"><rect x="{thickness}" y="{thickness}" rx="20" ry="20" width="{iw}" height="{ih}" fill="white"/></svg>'
png = svg2png(bytestring=inner)
inner = Image.open(BytesIO(png)).convert('L')
# Expand original canvas with black to match output size
expanded = ImageOps.expand(im, border=thickness, fill=(0,0,0)).convert('RGB')
# Paste expanded image onto outer black border using inner white rectangle as mask
outer.paste(expanded, None, inner)
return outer
# Open image, frame it and save
im = Image.open('monsters.jpg')
result = frame(im, thickness=10)
result.save('result.png')
输出图像
输入图像
您可以使用rx
并ry
更改拐角的半径。
这里是outer
,inner
和expanded
- 正如你所看到的,它们的大小都相同,以便于在彼此之上组合。
其他想法:
- 您还可以通过在黑盒子中绘制一个白色矩形并在其上运行中值滤波器或一些形态腐蚀来创建圆角。如果你过滤这个:
使用 15x15 中值滤波器,你会得到:
以防万一有人想要ImageMagick解决方案:
#!/bin/bash
# Get width and height of input image
read iw ih < <(identify -format "%w %h" monsters.jpg)
# Calculate size of output image, assumes thickness=10
((ow=iw+20))
((oh=ih+20))
magick -size ${ow}x${oh} xc:none -fill black -draw "roundrectangle 0,0 $ow,$oh 20,20" \
\( -size ${iw}x${ih} xc:black -fill white -draw "roundrectangle 0,0,$iw,$ih 20,20" monsters.jpg -compose darken -composite \) \
-gravity center -compose over -composite result.png
关键词:Python、图像处理、圆角、圆角、边框、SVG、cairo、cairosvg、SVG 到 PNG、SVG 作为 PNG、SVG 到 PIL、PIL、Pillow。
推荐阅读
- java - 仅对数组中的偶数进行排序,不要触及赔率
- inno-setup - Inno Setup Disable Next 按钮使用多个验证表达式(当输入值与多个值之一匹配时)
- sql - 替换 blob 中的文本
- java - 如何在 Mirth 中部署具有 HTTP Sender 连接器类型的通道作为目标?
- assembly - 如何识别存储的指令 LC-3
- dart - 飞镖中的NoSuchMethod?
- java - minikube 中损坏的 jar
- javascript - 无法从 db.ref('reference').orderByChild('child').equalTo('value').ref 返回正确的引用;
- android - 具有不同范围的 Dagger 2 碎片
- c - 重复连接和断开操作时 ODBC32.lib 中的内存泄漏