How to increase RGB value of a specific pixel using Image :: Magic in Perl?

I want to get 1 pixel (x=3, y=3) and change its RGB values ​​(R from 100 to 101 , G from 99 to 100 , B from 193 to 194 ).

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? 

How to add 1 for all RGB components?

Can I divide the decimal RGB into 3 values ​​(r, g, b) and the increment separately, and then combine the three values ​​of R, G, B into one RGB? :) How to do this?

  $pix = .... something code here... # make changes $p->SetPixel( x => 3, y => 3, channel => 'RGB', color => [ $pix ] ); $p->Write ('my_new_file.jpg'); 
+5
source share
1 answer

It was a little hard to understand, but here we go. I will show you what I did to get the result, not just how it works.

I use a small image with an initial color (100, 99, 193) .

initial image and color

At the top of my program, I will always have this code.

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

I checked the documentation at imagemagick.org . He is connected in Image :: Magic in CPAN . There I searched for GetPixel . This provides two useful things. One of them is an explanation, another example that shows that the @pixel array is @pixel , not the scalar as you tried.

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

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

Ok Let me use this. I already have @pixel in my code above. Note that I also enabled the normalize option. You can leave this as default.

 p @pixel; # [ # [0] 0.392156862745098, # [1] 0.388235294117647, # [2] 0.756862745098039 # ] 

So this is a float. After some googling, I found this answer , which concerns something similar. It looks like part 255 . Let it multiply. We can change things in @pixel by assigning $_ to postfix foreach . This is neat.

 $_ *= 255 foreach @pixel; p @pixel; # [ # [0] 100, # [1] 99, # [2] 193 # ] 

This is what we wanted. Easy enough. Add one each.

 $_ = ( $_ * 255 ) + 1 foreach @pixel; p @pixel; # [ # [0] 101, # [1] 100, # [2] 194 # ] 

Still good. But how can we get this back? Documents can say something about SetPixel in the Manipulate section.

color => array of float values
[...]
set one pixel. By default, normalized pixel values ​​are expected.

Looks like we need to get back to the float. No problems.

 $_ = ( ( $_ * 255 ) + 1 ) / 255 foreach @pixel; p @pixel; # [ # [0] 0.396078431372549, # [1] 0.392156862745098, # [2] 0.76078431372549 # ] 

Nice. Of course, we can make the math a little shorter. The result is the same.

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

Now back to the image.

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

In the screenshot, I changed it by adding 20 instead of 1 to make it more visible.

New image with +20, including freehand circles

After cleaning, the code is as follows.

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

I removed the map and channel arguments from GetPixel and SetPixel as RGB by default. The same goes for normalize .

+5
source

Source: https://habr.com/ru/post/1233755/


All Articles