Question about batch processing, and kudos

IMagick is a native PHP extension to create and modify images using the ImageMagick API. ImageMagick Studio LLC did not write nor does it maintain the IMagick extension, however, IMagick users are welcome to discuss the extension here.
Post Reply
flashape

Question about batch processing, and kudos

Post by flashape »

First off, I have been messing around with the IMagick extension, and from what I have seen so far I am loving it. THANK YOU so much for that to whoever is responsible.

So, I have a question about batch processing a folder of images. My situation is that I have a folder with about 1,000 jpgs in it. I need to composite a small png graphic in each frame. The catch is that the png's x,y,width,height, and rotation values are going to be different on every frame.

Currently what I have works fine, but I don't feel like it is the most efficient. Here is what the php code looks like:

Code: Select all

$num = count($positions);
		
		$headFile = 'temp/head.png';

		$res='';
		for($i = 1; $i<$num; $i++){
			$pos = $positions[$i-1];
			
			
			$frame = new Imagick('temp/frame'.$i.'.png');
			
			if( $pos['valid']){
			
				$w = $pos['width'];
				$h = $pos['height'];
			
				$x = ceil( $pos['x'] );
				$y = ceil( $pos['y'] - 10 );
			
				$rot = ceil( $pos['rotation'] );
				
				$head = new Imagick($headFile);
				
				
				$head->resizeImage($w ,$h,Imagick::FILTER_LANCZOS,1);
				$head->rotateImage('transparent',$rot);
				$frame->compositeImage($head, $head->getImageCompose(), $x, $y);
			}
			
			
			$frame->writeImage('output/frame'.$i.'.jpg');
			
		}
The idea is:
-loop through an array of objects which contains info on how to position the png on each frame
- open the background image ($frame)
- read the head image
- compose the head onto the frame
- save the composed image as a new file

As you can see, I am re-creating the $head file every time through the loop, because it will be modified every time it runs. Is there a more efficient way to do this? Or a better way to do all of it?
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Question about batch processing, and kudos

Post by mkoppanen »

Something like this maybe:

Changes:
a) read head image only once and clone it when needed
b) use thumbnailImage instead resizeImage (strips image profiles and comments)
c) Use Imagick::COMPOSITE_OVER constant instead of fetching Composite operator every time
d) Use the same frame object on each iteration, just clean it after use

Code: Select all

<?php

$frame = new Imagick();
$head = new Imagick( 'temp/frame' . $i . '.png' );

$num = count($positions);
$res='';

for ( $i = 1; $i < $num; $i++ )
{
	$pos = $positions[$i-1];
	$frame->readImage( 'temp/frame' . $i . '.png' );
	
	if ( $pos['valid'])
	{
		$w = $pos['width'];
		$h = $pos['height'];
	
		$x = ceil( $pos['x'] );
		$y = ceil( $pos['y'] - 10 );
	
		$rot = ceil( $pos['rotation'] );
	
		$tmpHead = $head->clone();
	
		$tmpHead->thumbnailImage( $w, $h );
		
		$tmpHead->rotateImage( 'transparent', $rot );
		
		$frame->compositeImage( $tmpHead, Imagick::COMPOSITE_OVER, $x, $y );
	
		$tmpHead->destroy();
	}
	
	$frame->writeImage( 'output/frame'.$i.'.jpg' );
	$frame->clear();
}
Mikko Koppanen
My blog: http://valokuva.org
flashape

Re: Question about batch processing, and kudos

Post by flashape »

thanks, that helped a lot, cut about 1/3 of processing time.
Post Reply