Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Manipulating pixels of an Image 3

Status
Not open for further replies.

exp110

Programmer
Joined
Oct 27, 2006
Messages
10
Location
GB
Hi,
can anyone recommend a module for me to use which will allow me to itterate through each pixel of an image and modify the R,G,B data for each pixel?

I really don't know how to do this but it is an important part of my program which I have almost finished except for this last bit.

I have an image saved as image.jpg (i can change this to bmp if necessary) and I want to open this in my perl program, and make the blue and green values of each pixel equal to the red value Xor'd with 255. I then want to be able to get the x,y co-ordinates for the pixel with the highest amount of red in it.

I am using windows/activeperl. Any help would be great, thanks!
 
use GD.


If you're on Windows, install it by going to command prompt and typing:

Code:
ppm install www.steveshipway.org/software/3rdparty/GD.ppd

(or search Google "gd ppd" and find another ppm source)

-------------
Kirsle.net | Kirsle's Programs and Projects
 
okay thanks, I will check it out :]
 
hmm im trying to install it like you said with ppm but it says that it 'is not intended for this build of perl MSWin32-x86-multi-thread' ... I have the latest version of activestate perl installed too :S
 
okay nevermind I installed it a diff way :)
 
Well, you could go about it manually.
Once you've opened and decompressed the image and stripped the header info out you're left with what you can think of as a grid. Assuming 24-bit color you have:
pixel1red pixel1blue pixel1green pixel2red pixel2green pixel2blue etc etc. To find all of the red values look at every 3rd value starting with zero, to find all blue look at every 3rd value starting with 2, etc. This should make it easy to find the highest RED value.

As far as X-Y coordinates you're going to need to know the image size in pixels. Say I have a 100x100 pixel image, 3 bytes per pixel means byte 300 would be row 2 column 1.

hth.
 
Err, badly stated, byte 300 would be the red value of x=2 y=1, byte 301 would be the green value of x=2 y=1 etc.
 
Hm, thanks I understand what you mean with the grid and 3 bytes per pixel :)

I have opened my image now using GD like this:

$myImage = newFromJpeg GD::Image('image.jpg') || die "Unable to open image\n";

you say that I have to decompress the image and strip the header info... does GD do this for me automatically?

The image I am working on is always 200x200 pixels. I am looking through the GD documentation and I think that I would probably need to use: $image->setPixel($x,$y,$color) to set each pixel to red xor byte255. Do you know how I can itterate through every pixel in my 200x200 image to do this though?
 
maybe:

Code:
my $file = 'frog.jpg';
my $image = GD::Image->newFromJpeg($file);
my %data= ();
foreach my $w (0..200) {
   foreach my $h (0..200) {
      my $index = $image->getPixel($w,$h);
      my ($r,$g,$b) = $image->rgb($index);
      $data{"$w,$h"}=???;
   }
}
foreach my $keys (sort {$data{$b} <=> $data{$a}} keys %data) {
   print "pixel - $keys = $data{$keys}\n";
}

But I don't understand how this operation is to be done:

make the blue and green values of each pixel equal to the red value Xor'd with 255

which is where '???' would probably be done in above code

- Kevin, perl coder unexceptional!
 
Wow thanks kevin, that code will help me a lot! :).
I will do some thinking and try and work out how to 'make the blue and green values of each pixel equal to the red value Xor'd with 255'.


Code:
#! /usr/local/bin/perl
use GD;
$image = newFromJpeg GD::Image('image.jpg') || die "Unable to open image\n";
my %data= ();
foreach my $w (0..200) {
   foreach my $h (0..200) {
      my $index = $image->getPixel($w,$h);
      my ($r,$g,$b) = $image->rgb($index);

      # set blue and green values = red xor 255 here...

      $data{"$w,$h"}=$r;
   }
}
$count = 0;
foreach my $keys (sort {$data{$b} <=> $data{$a}} keys %data) {
   last if $count == 1;
   print "pixel - $keys = $data{$keys}\n";
   $count += 1
}

Here I've just changed your code a bit to make it put the $r value in the in the hash and then the foreach loop to only return the highest red value. I think this would be right? :x But then all this has to happen after it has modified the green and blue pixels.

I don't know if this helps, but here is the same sort of thing which I am trying to do in perl, but done in visual basic .NET:


But I think your code is almost there kevin, so I just need to work out how to do the xor thing. Thanks again :)
 
Actually I got the xor thing mixed up :x
The only one that needs to be done is the red value of each pixel needs to be set equal to the blue value xor 255.
 
Woo done it :D
This works exactly how I wanted it to:)

Code:
#! /usr/local/bin/perl
use GD;
print "Opening image\n";
$image = newFromJpeg GD::Image('image.jpg') || die "Unable to open image\n";
print "Starting pixel modification\n";
my %data= ();
foreach my $w (0..200) {
   foreach my $h (0..200) {
      my $index = $image->getPixel($w,$h);
      my ($r,$g,$b) = $image->rgb($index);
	$r = ($b^255);
	$data{"$w,$h"} = $r;
   }
}
$count = 0;
foreach my $keys (sort {$data{$b} <=> $data{$a}} keys %data) {
   last if $count == 1;
   print "pixel - $keys = $data{$keys}\n";
   $count += 1
}

So thanks for the help kevin, I couldn't have done it without you!
 
You're welcome. [smile]

- Kevin, perl coder unexceptional!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top