[Melbourne-pm] Image Manipulation

Scott Penrose scottp at dd.com.au
Fri Apr 28 07:06:41 PDT 2006


Hey Guys

As part of my Gallery code I need a very minimal set of image  
manipulations.
It has been wisely suggested to me that it is not a good idea just to  
depend on something like Image::Magic. One reason for this is that  
some implementations of a Gallery back end (eg: Flickr) do all the  
work for you.

So I could have it that my implementations of a library (eg: my  
example Simple, which works purely on files and directories) could  
depend on the necessary code, eg: Image::Magick.

This is tricky though because it then means that the simplest of  
classes requires the most complicated code, and I would like to have  
the simple class, at least for testing.

A quick side track: For those of you who do not know, I am writing  
"Gallery::" (name yet to be confirmed) which is an abstract Gallery  
API that works with any backend. Think of it as the DBI for Galleries.

Then I was reading up on all of the library advantages and  
disadvantages.

Firstly, my requirements are fairly small, here is a simple list:

* resize - Resize an image, almost always scaled (proportional),  
mostly smaller

* height/width - I need it... get it for me.

* rotate - Only need to do CW/CCW 90 degree increments

* return objec handle (to library) - Nice to pass it back, since it  
already exists, eg: if the user wants to do more in the native library.

So then I went through as many of the CPAN libraries as I could, and  
here is a quick summary, mostly they include some code to do the  
resize as a sample. The braces on the right indicate the features it  
supports.

	Image::Magick (height/width, resize, object)
		
		my $im = Image::Magick->new;
		$im->Read(file=>$self->filehandle);
		$im->Scale(-geometry=>'250x250');

		# Note: Also returns height/width

	GD (height/width, resize, object)

		Ahhh too hard, use Image::Resize !

	Image::Resize - GD wrapper (height/width, resize, object)

		$image = Image::Resize->new('large.jpg');
		$gd = $image->resize(250, 250);

		# Note: Also returns height/width
		$gd->width(), $gd->height
		
	Imager (height/width, resize, object)

		$newimg = $img->copy();
		$newimg = $img->scale(xpixels=>400);
		$newimg = $img->scale(xpixels=>400, ypixels=>400);
		
	Image::Epeg - JPEG only, but very fast (height/width, resize)

		# Resize down only !
		# Can set commments

		my $epg = new Image::Epeg( "test.jpg" );
		$epg->resize( 150, 150, MAINTAIN_ASPECT_RATIO );
		$epg->write_file( "test_resized.jpg" );

	GFL::Image (height/width, resize, object)

		# Note: Very nice, but license issues (free, non-commercial)

		$im -> load("test.png");
		$im -> set( output => "jpeg", undolevel => 5);
		$im -> resize (320, 200);
		$im -> save("test.jpg");

	Image::Imlib (height/width, resize, object)

		my $image = Image::Imlib2->load("foo.png");
		$image2=$image->create_scaled_image(100,100);


	Image::Info (height/width)

		my $info = image_info("image.jpg");
		my($w, $h) = dim($info);
		
	Image::Filter - another GD wrapper (not enough)


So... down to where to from here...

Let me say that one of my requirements is to have little to no  
requirements on large, especially C based (and thus compiled)  
external modules. Sure, they are required to do resize (I am not  
reinventing here) but if you don't resize, the library still works...

It seems I have a few options on where to go...

1) Hard code a few of the libraries in my own specific order. Try to  
load them, on failure fall through to one that works, or report that  
we need at least something. I note that many of the Gallery PHP  
applications use this approach, or a static list of which modules are  
loaded.

2) Write a wrapper class inside Gallery to deal with the above,  
allowing people to add a new backend without changing the other bits  
of code. This also implies that the user would have the ability to  
define which are supported/tried and in what order. This could speed  
things up on a busy site - but the library would still automatically  
try in case it doesn't know - allowing for a Zero configuration,  
working library.

3) Write an external wrapper - yet another abstraction, just for the  
most basic of functions - height, width, resize, rotate... Really the  
same as 2 but make it more usable outside. A little harder to write,  
new tests, module space etc.

My current thoughts is leaning in on 2.

3 worries me a little for two reasons: It is an unnecessary  
abstraction - using the Simple driver of Gallery you can already  
achieve what you would otherwise with 3, so just use Gallery (this is  
a sort of); where would it go, it seems that people writing modules  
such as "Image::Resize" have this sort of in mind, but have limited  
to one function, and one backend.

So... over to you my active perl development team and friends. What  
do you think I should do ?

Scooter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
Url : http://mail.pm.org/pipermail/melbourne-pm/attachments/20060429/b0ce5032/attachment.bin 


More information about the Melbourne-pm mailing list