如何使用 ImageMagick blur/pixelate 部分图像导致大像素?
How to blur/pixelate part of an image using ImageMagick resulting in big pixels?
我正在使用 Perl 和 ImageMagick (Perl-API)。在第一步中,我拍摄了一个图像的矩形并模糊了图像的这一部分(加上该矩形的旋转)。
多亏了 Mark Setchell,它的工作原理如下(请参阅此处的 Whosebug 问题:)。
现在我的目标是用更大的像素模糊该图像的矩形。 我怎样才能做到这一点?
这里是我目前使用的 Mark Setchell 的代码:
#!/usr/bin/perl
use strict;
use warnings;
use Image::Magick;
my $x;
my $image;
my $blurred;
my $mask;
# Create original fishscale image
$image=Image::Magick->new(size=>'600x300');
$image->Read('pattern:fishscales');
$image->Write(filename=>"1.png");
# Copy original image and blur
$blurred = $image->Clone();
$blurred->GaussianBlur('x2');
$blurred->Write(filename=>"2.png");
# Make mask and rotate
$mask=Image::Magick->new(size=>'600x300');
$mask->Read('xc:white');
$mask->Draw(fill=>'black',primitive=>'rectangle',points=>'100,100,200,200');
$mask->Set('virtual-pixel'=>'white');
$mask->Rotate(20);
$mask->Transparent('white');
$mask->Write(filename=>"3.png");
# Copy mask as alpha channel into blurred image
$blurred->Composite(image=>$mask,qw(compose CopyOpacity gravity center));
# Composite blurred image onto original
$image->Composite(image=>$blurred);
$image->Write(filename=>'result.png');
更新:还有一个问题:
它可以很好地处理 select 没有旋转的矩形。但如果我应用一个角度,我会得到奇怪的结果。被像素化的区域不是我定义的区域,但它与我 select 远离图像中间的矩形 and/or 增加角度的差异越大。
查看下面的图片,其中包含不同的矩形 selected 和像素化的区域。我用的是45度角
知道这里的问题是什么吗?(也许 'compose CopyOpacity gravity center')
是这样的吗?
#!/usr/bin/perl
use strict;
use warnings;
use Image::Magick;
my $x;
my $image;
my $blurred;
my $mask;
# Create original fishscale image
$image=Image::Magick->new(size=>'600x300');
$image->Read('pattern:fishscales');
$image->Write(filename=>"1.png");
# Copy original image and scale
$blurred = $image->Clone();
$blurred->Resample(x=>'100',y=>'50',filter=>'point');
$blurred->Scale(width=>'1200',height=>'600');
$blurred->Write(filename=>"2.png");
# Make mask and rotate
$mask=Image::Magick->new(size=>'600x300');
$mask->Read('xc:white');
$mask->Draw(fill=>'black',primitive=>'rectangle',points=>'20,20,220,120');
$mask->Set('virtual-pixel'=>'white');
$mask->Rotate(20);
$mask->Transparent('white');
$mask->Write(filename=>"3.png");
# Copy mask as alpha channel into blurred image
$blurred->Composite(image=>$mask,qw(compose CopyOpacity gravity center));
# Composite blurred image onto original
$image->Composite(image=>$blurred);
$image->Write(filename=>'result.png');
我会接受 Mark Setchell 的回答,但 post 我对更新问题的解决方案在这里。我使用辅助函数,我只修改了 "Make mask and rotate" 部分。
# helperfunction
sub listDraw
{
my $image = shift;
my $result = undef;
for my $attrs (@_)
{
my ($left, $top, $width, $height, $angle) = delete @$attrs{qw(left top width height angle)};
if ($angle - int($angle/180)*180)
{
my ($xm, $ym, $rad) = ($left + $width/2, $top + $height/2, $angle * PI/180);
$attrs->{primitive} ||= 'Polygon';
$attrs->{points} = join ' ', map {($xm + ($_->{x}-$xm)*cos($rad) + ($_->{y}-$ym)*sin($rad)) . ',' . ($ym - ($_->{x}-$xm)*sin($rad) + ($_->{y}-$ym)*cos($rad))}
({ x => $left, y => $top }, { x => $left + $width, y => $top }, { x => $left + $width, y => $top + $height }, { x => $left, y => $top + $height });
}
else
{
$attrs->{primitive} ||= 'Rectangle';
$attrs->{points} ||= $left . ',' . $top . ' ' . ($left + $width - 1) . ',' . ($top + $height - 1);
}
last if $result = $image->Draw(%$attrs);
}
return $result;
}
# Make mask and rotate
$mask=Image::Magick->new(size=>'600x300');
$mask->Read('xc:white');
$mask = listDraw($mask, {
left => $selection_y, # y of top left corner
top => $selection_x, # x of top left corner
width => $selection_width,
height => $selection_height,
angle => 180 - $angle,
fill => 'black',
});
$mask->Set('virtual-pixel' => 'white');
$mask->Transparent('white');
我正在使用 Perl 和 ImageMagick (Perl-API)。在第一步中,我拍摄了一个图像的矩形并模糊了图像的这一部分(加上该矩形的旋转)。
多亏了 Mark Setchell,它的工作原理如下(请参阅此处的 Whosebug 问题:
现在我的目标是用更大的像素模糊该图像的矩形。 我怎样才能做到这一点?
这里是我目前使用的 Mark Setchell 的代码:
#!/usr/bin/perl
use strict;
use warnings;
use Image::Magick;
my $x;
my $image;
my $blurred;
my $mask;
# Create original fishscale image
$image=Image::Magick->new(size=>'600x300');
$image->Read('pattern:fishscales');
$image->Write(filename=>"1.png");
# Copy original image and blur
$blurred = $image->Clone();
$blurred->GaussianBlur('x2');
$blurred->Write(filename=>"2.png");
# Make mask and rotate
$mask=Image::Magick->new(size=>'600x300');
$mask->Read('xc:white');
$mask->Draw(fill=>'black',primitive=>'rectangle',points=>'100,100,200,200');
$mask->Set('virtual-pixel'=>'white');
$mask->Rotate(20);
$mask->Transparent('white');
$mask->Write(filename=>"3.png");
# Copy mask as alpha channel into blurred image
$blurred->Composite(image=>$mask,qw(compose CopyOpacity gravity center));
# Composite blurred image onto original
$image->Composite(image=>$blurred);
$image->Write(filename=>'result.png');
更新:还有一个问题:
它可以很好地处理 select 没有旋转的矩形。但如果我应用一个角度,我会得到奇怪的结果。被像素化的区域不是我定义的区域,但它与我 select 远离图像中间的矩形 and/or 增加角度的差异越大。
查看下面的图片,其中包含不同的矩形 selected 和像素化的区域。我用的是45度角
知道这里的问题是什么吗?(也许 'compose CopyOpacity gravity center')
是这样的吗?
#!/usr/bin/perl
use strict;
use warnings;
use Image::Magick;
my $x;
my $image;
my $blurred;
my $mask;
# Create original fishscale image
$image=Image::Magick->new(size=>'600x300');
$image->Read('pattern:fishscales');
$image->Write(filename=>"1.png");
# Copy original image and scale
$blurred = $image->Clone();
$blurred->Resample(x=>'100',y=>'50',filter=>'point');
$blurred->Scale(width=>'1200',height=>'600');
$blurred->Write(filename=>"2.png");
# Make mask and rotate
$mask=Image::Magick->new(size=>'600x300');
$mask->Read('xc:white');
$mask->Draw(fill=>'black',primitive=>'rectangle',points=>'20,20,220,120');
$mask->Set('virtual-pixel'=>'white');
$mask->Rotate(20);
$mask->Transparent('white');
$mask->Write(filename=>"3.png");
# Copy mask as alpha channel into blurred image
$blurred->Composite(image=>$mask,qw(compose CopyOpacity gravity center));
# Composite blurred image onto original
$image->Composite(image=>$blurred);
$image->Write(filename=>'result.png');
我会接受 Mark Setchell 的回答,但 post 我对更新问题的解决方案在这里。我使用辅助函数,我只修改了 "Make mask and rotate" 部分。
# helperfunction
sub listDraw
{
my $image = shift;
my $result = undef;
for my $attrs (@_)
{
my ($left, $top, $width, $height, $angle) = delete @$attrs{qw(left top width height angle)};
if ($angle - int($angle/180)*180)
{
my ($xm, $ym, $rad) = ($left + $width/2, $top + $height/2, $angle * PI/180);
$attrs->{primitive} ||= 'Polygon';
$attrs->{points} = join ' ', map {($xm + ($_->{x}-$xm)*cos($rad) + ($_->{y}-$ym)*sin($rad)) . ',' . ($ym - ($_->{x}-$xm)*sin($rad) + ($_->{y}-$ym)*cos($rad))}
({ x => $left, y => $top }, { x => $left + $width, y => $top }, { x => $left + $width, y => $top + $height }, { x => $left, y => $top + $height });
}
else
{
$attrs->{primitive} ||= 'Rectangle';
$attrs->{points} ||= $left . ',' . $top . ' ' . ($left + $width - 1) . ',' . ($top + $height - 1);
}
last if $result = $image->Draw(%$attrs);
}
return $result;
}
# Make mask and rotate
$mask=Image::Magick->new(size=>'600x300');
$mask->Read('xc:white');
$mask = listDraw($mask, {
left => $selection_y, # y of top left corner
top => $selection_x, # x of top left corner
width => $selection_width,
height => $selection_height,
angle => 180 - $angle,
fill => 'black',
});
$mask->Set('virtual-pixel' => 'white');
$mask->Transparent('white');