【问题标题】:How do I increase the RGB value of a specific pixel with Image::Magic in Perl?如何在 Perl 中使用 Image::Magic 增加特定像素的 RGB 值?
【发布时间】:2016-01-13 11:15:02
【问题描述】:

我想要 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');

【问题讨论】:

    标签: linux perl imagemagick perl-module


    【解决方案1】:

    这有点难以弄清楚,但我们开始吧。我会告诉你我做了什么来得到结果,而不仅仅是它是如何工作的。

    我正在使用您的起始颜色为(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.。它在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 的一小部分。让我们相乘。我们可以通过在后缀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=>浮点值数组
    [...]
    设置单个像素。默认情况下,需要归一化的像素值。

    所以显然我们需要回到浮动。没问题。

    $_ = ( ( $_ * 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 也一样。

    【讨论】:

    • 非常详尽的答案!抱歉英语不好。
    • @Anton 不要担心英语。很好理解。我对其进行了一些修复以改善问题。请不要将其视为对您技能的批评。这是我们在这里所做的事情之一:尝试提高 SO 上内容的整体质量。毕竟,这是一个知识集合。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多