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

How do I increase the RGB value of a specific pixel with Image::Magic in Perl?

我想要获取 1 个像素 (x=3, y=3) 并更改其 RGB 值(R 从 100101,G 从 99100,B从 193194).

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 组件添加 1

我能否将十进制 RGB 拆分为 3 个值 (r,g,b) 并分别递增, 然后将三个 R、G、B 值合并为一个 RGB? :) 我该怎么做?

   $pix = .... something code here...

   # make changes
   $p->SetPixel(
            x       => 3,
            y       => 3,
            channel => 'RGB',
            color   => [ $pix ]
        );
   $p->Write ('my_new_file.jpg');

这有点难以理解,但我们开始吧。我将向您展示我为获得结果所做的工作,而不仅仅是它是如何工作的。

我正在使用具有您的起始颜色的小图像 (100, 99, 193)

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

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.. It is linked in Image::Magick on CPAN. There I searched GetPixel. That yields two helpful things. One is the explanation, the other one an example,表明返回了一个数组 @pixel,而不是像您尝试的那样的标量。

Here we reduce the intensity of the red component at (1,1) by half:

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

好的。让我们使用它。我已经在上面的代码中得到了 @pixel 。请注意,我还打开了 normalize 选项。您可以将其保留在默认情况下。

p @pixel;

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

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

$_ *= 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=>array of float values
[...]
set a single pixel. By default normalized pixel values are expected.

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

$_ = ( ( $_ * 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,因此它更加明显。

清理后的代码如下所示。

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');

我已经从 GetPixelSetPixel 中删除了 mapchannel 参数,因为 RGB 是默认值。 normalize.

也一样