2015-10-15 52 views
5

我想要得到1個像素(x=3, y=3)和(從99ř從100101,G至100,B從193194)改變其RGB值。如何在Perl中使用Image :: Magic增加特定像素的RGB值?

enter image description here

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? 

如何添加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'); 
+0

這很有趣。 :) – simbabque

回答

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的一小部分。我們乘以。我們可以通過在後綴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的說法。

顏色=>浮子的數組值
[...]
設置單個像素。默認情況下,標準化的像素值是預期的。

顯然我們需要回到浮動狀態。沒問題。

$_ = (($_ * 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'); 

我從GetPixel刪除mapchannel參數和SetPixelRGB是默認的。 normalize也是如此。

+0

非常詳盡的答案!對不起英語不好。 –

+0

@Anton不要擔心英語。這很好理解。我修正了一些問題以改善問題。不要把它看作是對你的技能的批評。這是我們在這裏所做的一件事:嘗試提高SO上內容的整體質量。畢竟,這是一個知識收集。 :) – simbabque

+0

很好的回答。 +1 –