如何使用Perl中的Image :: Magic增加特定像素的RGB值?

时间:2015-10-15 06:06:46

标签: linux perl imagemagick perl-module

我希望获得1个像素(x=3, y=3)并将其RGB值(R从100更改为101,G从99更改为100,B从{更改{1}}到193)。

enter image description here

194

如何为所有RGB组件添加use strict; use Image::Magick; my $p = new Image::Magick; $p->Read( 'myfile.jpg' ); my $pix = $p->GetPixel( width => 1, height => 1, x => 3, y => 3, map => 'RGB', normalize => 0 ); # in $pix RGB value now?

我可以将十进制RGB分成3个值(r,g,b)并单独递增, 然后将三个R,G,B值合并为一个RGB? :)我该怎么做?

1

1 个答案:

答案 0 :(得分:5)

要弄清楚这有点棘手,但我们走了。我会告诉你我做了什么来得到结果,而不仅仅是它是如何工作的。

我正在使用一个具有起始颜色(100, 99, 193)的小图片。

starting image and color

在我的程序的顶部,我将始终拥有此代码。

use strict;
use warnings;
use Data::Printer;
use Image::Magick;
my $p = new Image::Magick;
$p->Read('33141038.jpg');

my @pixel = $p->GetPixel(
    x         => 1,
    y         => 1,
    map       => 'RGB',
    normalize => 1,
);

我查了the documentation at imagemagick.org.。它在Image::Magick on CPAN中链接。在那里我搜索了GetPixel。这产生两个有用的东西。一个是解释,另一个是an example,表示返回了一个数组@pixel,而不是你尝试过的标量。

  

这里我们将(1,1)处红色成分的强度降低一半:

@pixels = $image->GetPixel(x=>1,y=>1);

确定。让我们用它。我上面的代码中已经有了@pixel。请注意,我还打开了normalize选项。默认情况下,您可以将其保留为打开状态。

p @pixel;

# [
#     [0] 0.392156862745098,
#     [1] 0.388235294117647,
#     [2] 0.756862745098039
# ]

所以这些都是花车。经过一些谷歌搜索后,我找到this answer,它处理类似的事情。它看起来像255的一小部分。让我们相乘。我们可以通过在后缀@pixel中分配$_来修改foreach中的内容。那很好。

$_ *= 255 foreach @pixel;
p @pixel;

# [
#     [0] 100,
#     [1] 99,
#     [2] 193
# ]

这就是我们想要的。很容易。我们分别加一个。

$_ = ( $_ * 255 ) + 1 foreach @pixel;
p @pixel;

# [
#     [0] 101,
#     [1] 100,
#     [2] 194
# ]

仍然很好。但是我们如何重新开始呢?文档对Manipulate section中的SetPixel有所说明。

  

color =>浮点值数组
  [...]
  设置一个像素。默认情况下,预期会有标准化的像素值。

显然我们需要回到浮动状态。没问题。

$_ = ( ( $_ * 255 ) + 1 ) / 255 foreach  @pixel;
p @pixel;

# [
#     [0] 0.396078431372549,
#     [1] 0.392156862745098,
#     [2] 0.76078431372549
# ]

尼斯。我们当然也可以让数学更短一些。结果是一样的。

$_ = $_ + 1 / 255 foreach @pixel;

现在让我们把它写回图像。

$p->SetPixel(
    x => 1,
    y => 1,
    color => \@pixel, # need the array ref here
);

$p->Write('my_new_file.jpg');

在屏幕截图中,我将其更改为添加20而不是1,以便更加明显。

New image with +20 including freehand circles

清理后代码看起来像这样。

use strict;
use warnings;
use Data::Printer;
use Image::Magick;

my $p = new Image::Magick;
$p->Read('33141038.jpg');

my @pixel = $p->GetPixel(
    x => 1,
    y => 1,
);

# increase RGB by 1 each
$_ = $_ + 1 / 255 foerach @pixel;

$p->SetPixel(
    x     => 1,
    y     => 1,
    color => \@pixel,
);

$p->Write('my_new_file.jpg');

我已从mapchannel删除了GetPixelSetPixel个参数,因为RGB是默认值。与normalize相同。