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 bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Getting JPEG Dimensions w/o ImageMagic?

Status
Not open for further replies.

millimeter

Programmer
Mar 30, 2002
12
US
Howdy,

Does anyone one have a Perl script that will get JPEG image dimensions (width/height) without ImageMagic?

I basically want to glob through an image dir and return or print the dimensions. I can do the basic globing, opening, or reading...etc.

But I have spent many hours working with a few things I have found... NO WORKIE.

Thanks in advance.
 
By replying I am biting off more than I can chew, but I think...

my $width = $image->Get('width' );
my $height = $image->Get('height');
 
This one really pissed me off. I have done work with TARGA (.tga) files in the past, and there was a nice, simple header I could work with. JPEG documentation isn't nearly as good, and it doesn't even really have an image header. JPEG files start with a unique two byte code, then are also into "marker" sections. Each marker is a two byte value, the first being FF, the next being unique for a marker. After each marker is a two byte unsigned integer for the length of that marker's information (this length does not include the marker itself, but it does include the two bytes for the length...strange system if you ask me). You have to loop over these markers until you get to the one that contains the info you're after. Here was my JPEG reference page, then onto the code:
Code:
use strict;
use warnings;

for(glob '*.jpg')
{
	open FILE, "$_" or die "Unable to open $_\n$!";
	binmode FILE;
	my $buffer;
	
	#first two bytes are always the identifier FFD8 in a JPEG File Interchange Format (JFIF)
	sysread FILE, $buffer, 2;
	die "Not a JPEG file.\n" unless(unpack('n', $buffer) == hex('FFD8'));
	
	#there are a number of markers in a jpeg, each starting with FF
	#the next two bytes after every marker is the length of the content
	#of that marker, including the size, but not the marker itself
	#the frame marker (FFC0) contains the image size
	
	#read the next marker
	sysread FILE, $buffer, 2;
	
	#scan over the markers until the frame marker is found
	while(unpack('n',$buffer) != hex('FFC0'))
	{
		#read the length
		sysread FILE, $buffer, 2;
		
		#move the file pointer to the next marker
		sysseek FILE, unpack('n', $buffer) - 2, 1;
		
		#read the next marker
		sysread FILE, $buffer, 2;
	}
	
	#read the length
	sysread FILE, $buffer, 2;
	
	#read the frame marker
	sysread FILE, $buffer, unpack('n', $buffer) - 2;
	
	#not wanted data
	substr $buffer, 0, 1, '';
	
	#the next two words (two byte blocks) are the height and width
	my $height = unpack('n', substr $buffer, 0, 2, '');
	my $width = unpack('n', substr $buffer, 0, 2, '');
	
	print "$_\nWidth: $width\tHeight: $height\n\n";
	
	close FILE;
}
This hasn't been tested a whole lot, but it appears to work from what I've done. Lemme know what you think, if there's any problems or such. Here to help. ----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top