有背景图片。 (对于此示例,
mesh.png
)
给图片添加一个圆圈,边框模糊。目前有这个:
use 5.014;
use warnings;
use Image::Magick;
my $bgimg = Image::Magick->new();
$bgimg->Read('png:mesh.png');
draw_my_circle($bgimg, 150, 150, 100); #img, center_x, center_y, radius
$bgimg->Write("win:"); #display
sub draw_my_circle {
my($img, $center_x, $center_y, $radius) = @_;
$img->Draw(
fill => 'black',
points => "$center_x,$center_y @{[$center_x + $radius]},$center_y",
primitive => 'circle',
);
}
这会产生下一张图像:
但我需要一个“边缘模糊”的圆圈,就像下一个(手动创建)
任何人都可以帮助如何使用 Image::Magick 获得如此模糊的圆圈吗?
如果有人想要
mesh.png
,则使用下一个脚本创建它:
use 5.014;
use warnings;
use Image::Magick;
my $image=Image::Magick->new(size=>'300x300');
$image->Read('xc:white');
for( my $i=0; $i < 300; $i += 10 ) {
$image->Draw(primitive=>'line',points=>"$i,0 $i,300",stroke=>"#ccf");
$image->Draw(primitive=>'line',points=>"0,$i 300,$i",stroke=>"#ccf");
}
$image->Write('png:mesh.png');
您可以使用高斯模糊,如下所示:
#!/usr/bin/perl
use 5.014;
use strict;
use warnings;
use Image::Magick;
my $x;
my $circle;
my $mesh;
$mesh=Image::Magick->new(size=>'300x300');
$mesh->Read('xc:white');
for( my $i=0; $i < 300; $i += 10 ) {
$mesh->Draw(primitive=>'line',points=>"$i,0 $i,300",stroke=>"#ccf");
$mesh->Draw(primitive=>'line',points=>"0,$i 300,$i",stroke=>"#ccf");
}
$mesh->Write(filename=>'mesh.png');
$circle=Image::Magick->new(size=>'300x300');
$circle->ReadImage('xc:transparent');
$circle->Draw(
fill => 'black',
points => "150,150 @{[250]},100",
primitive => 'circle',
);
$circle->GaussianBlur('10x50');
$circle->Write(filename=>'circle.png');
$mesh->Composite(image => $circle, qw(compose SrcAtop gravity Center));
$mesh->Write(filename=>'out.png');
这是一个非常古老的线程,但它仍然有用。
高斯模糊的一个问题是它不能很好地扩展到非常高的分辨率。对于高分辨率图像,我使用渐变透明度的同心圆来代替。挑战是我不能仅仅对透明度进行线性分级,因为内圈也与外圈重叠。所以我计算了每一层的增量透明度,以相对于立即变大的图层的不透明度来增加该区域对目标的不透明度。
以下代码是在“wand”python 库中编写的。这里的“半径”是模糊圆所需的外半径。内半径设置为其一半。 “image”是图像对象。
我不能保证这段代码,因为我是一个Python新手:
# background
nShades = 128
stderr.write(f"rendering {nShades} shaded background circles...\n")
bgMinR = 0.5 * radius
bgMaxR = radius
with Drawing() as draw:
draw.gravity= "center"
draw.stroke_color = "none"
draw.stroke_width= 0
draw.stroke_fill= "none"
draw.antialias = False
transparency = 1
for i in range(0, nShades, 1):
# target transparency for this line
t = (nShades - i) / nShades
# stroke width for this line
r = (bgMaxR * (nShades - 1 - i) + bgMinR * i) / (nShades - 1)
# target transparency for this line
# how much alpha we need to get this transparency
# transparency * (1 - alpha/0xff) = t
# (1 - alpha)/0xff = t/transparency
# alpha/0xff = 1 - t/transparency
# alpha = 0xff * (1 - t/transparency)
alpha = int(0xff * (1 - t/transparency))
transparency *= (1 - alpha / 0xff)
draw.fill_color = "#000000%02x" % alpha
draw.circle((xc, yc), (xc + r, yc))
draw(image)