2015-10-15 27 views
5

Voglio ottenere 1 pixel (x=3, y=3) e cambiare i suoi valori RGB (R 100-101, G da 99 a 100, B 193-194).Come aumentare il valore RGB di un pixel specifico con Image :: Magic in Perl?

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? 

Come faccio ad aggiungere 1 per tutti i componenti RGB?

Posso dividere RGB decimale a 3 valori (r, g, b) e incrementare separatamente, e quindi unire tre valori R, G, B su un RGB? :) Come lo faccio?

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

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

E 'stato divertente. :) – simbabque

risposta

5

Questo è stato un po 'difficile da capire, ma ci siamo. Ti mostrerò cosa ho fatto per ottenere il risultato, non solo come funziona.

Sto usando una piccola immagine con il colore iniziale (100, 99, 193).

starting image and color

Nella parte superiore del mio programma avrò sempre questo codice.

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

ho controllato the documentation at imagemagick.org.. È collegato in Image::Magick on CPAN. Lì ho cercato GetPixel. Ciò produce due cose utili. Una è la spiegazione, l'altra an example che mostra che viene restituito un array @pixel e non uno scalare come si è tentato.

Qui ridurre l'intensità della componente rossa (1,1) della metà:

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

Ok. Usiamolo. Ho già ottenuto il @pixel nel mio codice qui sopra. Si noti che ho anche attivato l'opzione normalize. Puoi lasciarlo come attivo per impostazione predefinita.

p @pixel; 

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

Quindi quelli sono galleggianti. Dopo qualche ricerca su google ho trovato this answer, che tratta qualcosa di simile. Sembra una frazione di 255. Moltiplichiamo. Possiamo modificare le cose in @pixel assegnando a $_ nel suffisso foreach. È pulito

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

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

Questo è quello che volevamo. Abbastanza facile Aggiungiamone uno ciascuno.

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

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

Ancora buono. Ma come possiamo riaverlo? I documenti hanno qualcosa da dire su SetPixel nel Manipulate section.

colore => array di float valori
[...]
impostare un singolo pixel. Per impostazione predefinita, sono previsti valori di pixel normalizzati.

Quindi a quanto pare abbiamo bisogno di tornare al galleggiante. Nessun problema.

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

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

Nice. Ovviamente possiamo anche rendere la matematica un po 'più breve. Il risultato è lo stesso.

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

Ora scriviamo di nuovo all'immagine.

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

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

Nello screenshot, l'ho cambiato per aggiungere 20 invece di 1 quindi è più visibile.

New image with +20 including freehand circles

Dopo aver pulito il codice simile a questo.

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

ho rimosso le map e channel argomenti da GetPixel e SetPixel come RGB è l'impostazione predefinita. Lo stesso vale per lo normalize.

+0

Risposta molto esauriente! Scusa per il pessimo inglese. –

+0

@Anton Non preoccuparti per l'inglese. Va bene a capire. L'ho risolto un po 'per migliorare la domanda. Non vederlo come una critica alle tue capacità per favore. È una delle cose che facciamo qui: prova a migliorare la qualità generale del contenuto su SO. Dopotutto, è una raccolta di conoscenze. :) – simbabque

+0

Ben risposto. +1 –

Problemi correlati