在圆形图片周围生成平滑白色边框
我正在使用pgmagick来生成一个圆形缩略图。我采用的过程和这里讨论的类似,这确实能给我生成一个不错的圆形缩略图。不过,我需要在圆的边缘加一个白色的边框。
我最开始的想法是创建一个稍微大一点的白色圆形图像,背景透明,然后把缩略图放在上面,让白色圆形从缩略图下面“露出来”,形成边框效果。以下是我用来实现这个效果的pgmagick代码:
border_background = Image(Geometry(220, 220), Color('transparent'))
drawer = Draw()
drawer.circle(110, 110, 33.75, 33.75)
drawer.fill_color(Color('white'))
drawer.stroke_antialias(False)
border_background.draw(drawer.drawer)
border_background.composite(original_thumbnail, 0, 0, CompositeOperator.OverCompositeOp)
这个方法“有效”,但周围的白色边框看起来有点扭曲,边缘也很粗糙——不适合正式使用。如果我去掉drawer.stroke_antialias(False),效果会更糟。
有没有什么办法可以让这个边框在使用pgmagick时看起来更平滑呢?
2 个回答
如果你换个方法,结果会更好:
# First draw the thumbnail inside the circle.
background = Image(Geometry(220, 220), Color('transparent'))
drawer = Draw()
drawer.circle(110, 110, 33.75, 33.75)
drawer.fill_color(Color('white'))
background.draw(drawer.drawer)
background.composite(original_thumbnail, 0, 0, CompositeOperator.InCompositeOp)
# Draw only the border of the circle on top of the thumbnail inside the circle
border = Image(Geometry(220, 220), Color('transparent'))
drawer.fill_color(Color('transparent'))
drawer.stroke_color(Color('white'))
drawer.stroke_width(3)
border.draw(drawer.drawer)
background.composite(border, 0, 0, CompositeOperator.OverCompositeOp)
我留给读者一个简单的练习,就是把这个解决方案从命令行转换成pgmagick(下面会有更多说明)。pgmagick背后的代码和命令行用的是一样的。
你可以先画一个更大的圆圈,然后再把它“缩小”。这样在缩小的过程中,可以通过和周围背景的颜色进行平均,来改善圆圈边缘的锯齿感。
不要这样做:
gm convert -size 220x220 xc:none -fill white \
-draw "circle 110,110, 33.75,33.75" \
original.png
而是这样:
gm convert -size 880x880 xc:none -fill white \
-draw "circle 440,440, 135,135" \
-resize 25% resized.png
你可以尝试其他的大小,看看哪个是你觉得最小的,比如:
gm convert -size 440x440 xc:none -fill white \
-draw "circle 220,220, 67.5,65.5" \
-resize 50% resized.png
这个命令行在GraphicsMagick(“gm convert”)和ImageMagick(“convert”)上都能用。
查看pgmagick的文档,地址是http://pgmagick.readthedocs.org/en/latest/cookbook.html#scaling-a-image,你会发现pgmagick似乎没有提供“resize”这个功能。文档中显示的是“img.scale”,这可能会导致圆圈出现锯齿。用上面命令行示例中的“-scale”替代“-resize”,确实会产生同样的锯齿效果。
不过,pgmagick确实允许你指定滤镜类型,比如:
img.scale((150, 100), 'lanczos')
这应该和“-resize”是等价的,也是你想要的效果。