Learn / eZ Publish / Image Manipulation with eZ Components

Image Manipulation with eZ Components

About the eZ Components

The Image components we take a look at are a unified and consistent interface to functions available in PHP through external programs. Currently, two backend classes ship with eZ Components, which enable you to use the image manipulation programs ImageMagick (the external binary, not ext/imagick of PECL) or the GD extension bundled with PHP. This includes that the code you write with the eZ Components will work with either image library, thus you can switch them transparently without breaking your application. The components are also capable of selecting the most feasible backend for an action, if multiple are available.

Development Environment

In this article we assume that you have your environment already configured for running the eZ Components. Please read the introduction article for installation instructions. Notice that eZ Components need PHP 5.1 to work properly.

Scaling images for use on the Web is one of the most common programming tasks when handling images in an application for the WWW. You typically have a high resolution image you need to make available as smaller thumbnails. These thumbnails need to fit within a defined size, for example 150x100 pixels, but still keep the aspect ratio.

The PHP 5.1 script below shows how you can use the eZ components for scaling your images. The converter API called ezcImageConverter is the main class responsible for image conversion, scaling and effects. It is based on a plugin architecture. This architecture is designed for optimal loading of only the code actually needed, thus lowering the memory usage and making it cleanly extendable with custom functionality.

Autoload Routine

Let's take a close look at the sample code step by step; afterwards showing you the complete code. The first few lines show the autoloader routine which allows to automatically include an eZ components class. You can read more about it in the introduction article.

<?php
// Load autoloader functionality
require_once 'Base/base.php';
function __autoload( $className )
{  
    ezcBase::autoload( $className );
}
?>

Choosing the Image Backend

In this example we use the ImageMagick handler for image conversion. Both ImageMagick and GD provide very similar functionality. However, ImageMagick supports more image formats for conversion compared to GD. On the other side, GD is built as a PHP extension, while ImageMagick is a command line executable ? this makes GD faster in most situations.

<?php
// Define which handler to use for the image manipulation.
$settings = new ezcImageConverterSettings(
    array(
        new ezcImageHandlerSettings( 'GD', 'ezcImageGdHandler' ),
        new ezcImageHandlerSettings( 'ImageMagick', 'ezcImageImagemagickHandler' )
        )
    );
?>

Scaling Filters

Next, the scaling transformation we are going to perform needs to be defined. We do this in the $scaleFilters array, which describes the different filters we want to apply to the image. In this case, we only apply one filter called scale. We additionally specify image width and height as filter parameters. The images should only be scaled down if larger than the specified size.

<?php
// Define the filters to apply
$scaleFilters = array(
    new ezcImageFilter(
        'scale',
        array( 'width'    => 500,
               'height'   => 350,
               'direction' => ezcImageGeometryFilters::SCALE_DOWN
               )
        )
    );
?>

By assigning the constant ezcImageGeometryFilters::SCALE_DOWN to the direction parameter, the script will take care of this requirement.When using ezcImageGeometryFilters::SCALE_DOWN, please note that it makes the filter only scale images in one direction: from a large to a smaller size. To allow for both directions of scaling (small to large and large to small), use ezcImageGeometryFilter::SCALE_BOTH instead. The constants are summarized in this tabel:

Constant Scaling
ezcImageGeometryFilters::SCALE_DOWN Large to small
ezcImageGeometryFilters::SCALE_UP Small to large
ezcImageGeometryFilters::SCALE_BOTH Large to small and small to large

Execution

The definition of the transformation is done within the method $converter->createTransformation(). The $mimeTypes parameter limits the conversion to only output JPEG images. The transformation is given the name thumbnail and will be referenced later by this name (as a modified version of the singleton pattern). The actual transformation is being executed by the method $converter->transform(). There, we specify the transformation's name, as well as the source, and destination filename. Finally, we display the image in HTML by using PHP's print() function.

Sample Script and Result

Here comes the complete code, where you will also find further information about the script's functioning as inline comments to the source code. The sample code is available for download.

<?php
 
// Load autoloader functionality
require_once 'Base/base.php';
function __autoload( $className )
{  
    ezcBase::autoload( $className );
}
 
// Define which handler to use for the image manipulation.
$settings = new ezcImageConverterSettings(
    array(
       new ezcImageHandlerSettings( 'GD', 'ezcImageGdHandler' ),
        new ezcImageHandlerSettings( 'ImageMagick', 'ezcImageImagemagickHandler' )
        )
    );
 
// Create the converter object.
$converter = new ezcImageConverter( $settings );
 
// Define the filters to apply
$scaleFilters = array(
    new ezcImageFilter(
        'scale',
        array( 'width'    => 500,
               'height'   => 350,
               'direction' => ezcImageGeometryFilters::SCALE_DOWN
               )
        )
    );
 
// Which MIME types the conversion may output
$mimeTypes = array( 'image/jpeg' );
 
// Create the transformation inside the manager, this can be re-used
$converter->createTransformation( 'thumbnail', $scaleFilters, $mimeTypes );
 
// Transform an image.
$converter->transform( 'thumbnail', "boathouse.jpg", "boathouse_tumbnail.jpg" );
 
// Display the image after scaling
print( "<p><img src='boathouse_tumbnail.jpg' /></p>" );
?>

The script outputs a scaled-down version of the image as shown below.

When taking images with a digital camera, a lot of information about the image is stored as part of the image file. This includes for example the date of shooting, the shutter speed, the focal length, etc. This metadata can be quite useful to show to the visitors of your Web site together with the photo. Such information is stored in the EXIF format and it can be read with the help of eZ Components.

The code below shows how to analyze an image and fetch the EXIF information with eZ Components. We use the ezcImageAnalyzer class and create the analysis object stored in the $image PHP object.

Fetching the Image

First we define the image for retrieval and fetch its MIME type to check if it is a JPEG or TIFF, which are the formats currently supporting EXIF.

<?php
// Print image information
$image = new ezcImageAnalyzer( 'boat.jpg' );
 
$mime = $image->mime;
 
// Check if it's a photo format
if ( $mime == 'image/tiff' || $mime == 'image/jpeg' )
{
?>

Date Information

The date is directly available as a UNIX timestamp, providing the created date of the image file, which we format via the PHP date() function.

<?php
$date = date( 'd.m.Y', $image->data->date );
?>

Accessing EXIF Metadata

The actual EXIF information is available directly through the $image->data->exif variable. In this example we fetch the date, shutter speed, aperature and focal length. The shutter speed is being retrieved and its format is converted to fractions of a second, as this is the expected way of displaying this information, and then stored in the $shutterSpeed variable. The aperature is converted to an F stop number and stored in the $aperature variable. We also convert the focal length to a mm value for easier readability. These calculations will be directly available via the eZ Components in the forthcoming version 1.1. At the end of the script, EXIF information is printed out in human readable form.

Sample Script and Result

<?php
 
// Load autoloader functionality
require_once 'Base/base.php';
function __autoload( $className )
{
  ezcBase::autoload( $className );
}
 
// Print image information
$image = new ezcImageAnalyzer( 'boat.jpg' );
 
$mime = $image->mime;
 
// Check if it's a photo format
if ( $mime == 'image/tiff' || $mime == 'image/jpeg' )
{
    $date = date( 'd.m.Y', $image->data->date );
 
    // Calculate shutter speed in seconds
    $shutterSpeedArray = split( '/', $image->data->exif['EXIF']['ExposureTime'] );
    $shutterSpeed = "1/" . $shutterSpeedArray[1] / $shutterSpeedArray[0]  . " sec";
 
    $aperatureArray = split( '/', $image->data->exif['EXIF']['FNumber'] );
    $aperature = "F" . round( $aperatureArray[0] / $aperatureArray[1], 1 );
 
    $focalLengthArray = split( "/", $image->data->exif['EXIF']['FocalLength'] );
    $focalLength = round( $focalLengthArray[0] / $focalLengthArray[1], 2 ) . " mm";
 
    // Print information about the photo
    print( "<dl>
             <di>Photo taken on:</di><dd>$date</dd>
             <di>Shutter speed:</di><dd>$shutterSpeed</dd>
             <di>Aperature:</di><dd>$aperature</dd>
             <di>Focal:</di><dd>$focalLength</dd>
            </dl>" );
}
 
?>

The image used in the script is shown below.

The Output of the script is:

Photo taken on: 24.10.2005 

Shutter speed: 1/160 sec 

Aperature: F5 

Focal: 50 mm

Now comes a demonstration of how you can combine filters to images. Therefore, we will make a script which crops an image for better composition and converts it to grayscale.

Notice that the sample code is very similar to the scaling example we started with. This time, we have defined two more image filters: crop and colorspace. The crop filter will take a small part of the image, then the colorspace filter will turn the whole image into grayscale.

Additional Filters

Since much of the code is practically the same as the first example we can focus on the definition of the conversion filters in $filters. This is an array which contains three instances of the ezcImageFilter class.

The crop filter is defined by a start position in the original image measured by pixels on the x and y axis. The pixel size of the resulting crop is defined by the width and the height parameters. The colorspace filter simply converts the image to the defined colorspace. In this example we use the constant ezcImageColorspaceFilters::COLORSPACE_GREY to make the image gray scale.

The scale filter remains the same as in the first example. Accurately ordering the filters is important, as the first filter defined is the filter which is first executed. Hence, mixing up the order of crop and scale will cause undesired results.

Sample Script and Result

<?php
 
// Load autoloader functionality
require_once 'Base/base.php';
function __autoload( $className )
{
  ezcBase::autoload( $className );
}
 
// Define which handler to use for the image manipulation.
$settings = new ezcImageConverterSettings(
    array(
       new ezcImageHandlerSettings( 'GD', 'ezcImageGdHandler' ),
        new ezcImageHandlerSettings( 'ImageMagick', 'ezcImageImagemagickHandler' )
        )
    );
 
// Create the converter object.
$converter = new ezcImageConverter( $settings );
 
$filters = array(
    new ezcImageFilter(
        'crop',
        array( 'x' => 740,
               'width' => 1300,
               'y' => 720,
               'height' => 900
               )
        ),
    new ezcImageFilter(
        'colorspace',
        array(
            'space' => ezcImageColorspaceFilters::COLORSPACE_GREY
            )
        ),
    new ezcImageFilter(
        'scale',
        array( 'width'    => 500,
               'height'   => 350,
               'direction' => ezcImageGeometryFilters::SCALE_DOWN
               )
        )
    );
 
// Create the transformation inside the manager
$converter->createTransformation( 'crop', $filters, array( 'image/jpeg' ) );
 
// Transform an image.
$converter->transform( 'crop', "vulcher.jpg", "vulcher_converted.jpg" );
 
print( "<p><img src='vulcher_converted.jpg' /></p>" );
 
?>

The original image used in this example got colors and shows two birds:

This is how the converted image looks like, converted to gray and showing a small part of the original image, being the bird on the left side:

In this article we only scratched the surface of what you can do with image handling and the eZ Components and even with its various Image components. As this is an Open Source project, try out the examples yourself by downloading the sample code and installing eZ Components. The thorough documentation will help you to explore the functionality of image manipulation with eZ Components.

Resources