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

Ant*_*sov 5 linux perl perl-module imagemagick

我想得到1个像素(x=3, y=3)和(来自R改变其RGB值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? 
Run Code Online (Sandbox Code Playgroud)

如何1为所有RGB组件添加?

我可以将十进制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');
Run Code Online (Sandbox Code Playgroud)

sim*_*que 5

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

我正在使用一个有你的起始颜色的小图片(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,
);
Run Code Online (Sandbox Code Playgroud)

我查看了imagemagick.org上的文档..它在CPAN上的Image :: Magick中链接.在那里我搜索GetPixel.这产生两个有用的东西.一个是解释,另一个是显示返回数组的示例@pixel,而不是您尝试过的标量.

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

@pixels = $image->GetPixel(x=>1,y=>1);
Run Code Online (Sandbox Code Playgroud)

好.让我们用它.我已经@pixel在上面的代码中找到了.请注意,我也打开了该normalize选项.默认情况下,您可以将其保留为打开状态.

p @pixel;

# [
#     [0] 0.392156862745098,
#     [1] 0.388235294117647,
#     [2] 0.756862745098039
# ]
Run Code Online (Sandbox Code Playgroud)

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

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

# [
#     [0] 100,
#     [1] 99,
#     [2] 193
# ]
Run Code Online (Sandbox Code Playgroud)

这就是我们想要的.很容易.我们各添加一个.

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

# [
#     [0] 101,
#     [1] 100,
#     [2] 194
# ]
Run Code Online (Sandbox Code Playgroud)

还好.但是我们如何重新开始呢?文档SetPixelManipulate部分有话要说.

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

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

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

# [
#     [0] 0.396078431372549,
#     [1] 0.392156862745098,
#     [2] 0.76078431372549
# ]
Run Code Online (Sandbox Code Playgroud)

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

$_ = $_ + 1 / 255 foreach @pixel;
Run Code Online (Sandbox Code Playgroud)

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

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

$p->Write('my_new_file.jpg');
Run Code Online (Sandbox Code Playgroud)

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

包含写意圈的+20新图像

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

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');
Run Code Online (Sandbox Code Playgroud)

我已经删除了mapchannel参数的GetPixelSetPixel作为RGB是默认的.同样的normalize.