2016/10/30

How to crop an image in Magento 1.x

We can easily render an image in Magento through the delivered Varien_Image library.

Here is an example for a class method (e.g. for a helper):

public function getCroppedImage($imageSource,
        $top,
        $left,
        $right,
        $bottom)
    {
        $mediaPathSegment = "yourfolder/cache/";
        if(!$imageSource) {
            return false;
        }
        $destinationFilepath = Mage::getBaseDir('base') . "/media/" . $mediaPathSegment . basename($imageSource);

        // only render, if source file exists and destination file does not (to prevent rendering on every page request
        if(file_exists($imageSource) && !file_exists($destinationFilepath)) {
            // render image
            $imageObj = new Varien_Image($imageSource);
            // crop image
            $imageObj->crop($top, $left, $right, $bottom);
            // save to file
            $imageObj->save( $destinationFilepath );

            // return image url
            if(file_exists($destinationFilepath)) {
                // build url path to get image link for frontend
                return Mage::getBaseUrl('media') .$mediaPathSegment . basename($imageSource);
            } else {
                // if image could not be rendered fallback and return original image
                return $imageSource;
            }
        }
        return false;
    }

The parameter $imageSource has to be an absolute filepath to the image you want to render.

How crop() is working

Crop has four parameters: top, left, right and bottom. To understand how the crop method is working you take an imaginary line which is parallel to the side you set. If you increase the value, the imaginary line is moving to the opposite side of the image. Everything of the image that is between the specific image side and the imaginary line will be cut.

This means that

$imageObj->crop(10,10,10,10);

will cut 10 pixel from image on every side. The image will be 20 pixel smaller for width and height.
This also means, that the cropped image will keep the original ratio.

Cropping an image to a square

As another example I created a method that will cut an image to a square. This is needed sometimes to fit an image to a layout or a design. Images that are not the same format look ugly and uneasy.

/**
 * cropping images to square and resize
 *
 * @param string $imageFilename
 * @param int $resizeWidth in pixel
 * @return mixed returns new resized image url or false
 */
public function getSquareImageResized($imageFilename, $resizeWidth = null)
{
    if(!$imageFilename) {
        return false;
    }

    $mediaPathSegment = "yourfolder" . DS . "cache" . DS . "square_resized" . DS;
    $destinationFilepath = Mage::getBaseDir('base') . DS . "media" . DS . $mediaPathSegment . basename($imageFilename);

    if(file_exists($imageFilename)) {
        if(!file_exists($destinationFilepath)) {
            // render image
            $imageObj = new Varien_Image($imageFilename);
            // crop image
            $imageObj->constrainOnly( true );
            $imageObj->keepAspectRatio( true );
            $imageObj->keepFrame( false );

            // crop image
            $width = $imageObj->getOriginalWidth();
            $height = $imageObj->getOriginalHeight();

            // cut image to square
            if ($width > $height) {
                $diff = ($width-$height) / 2;
                $imageObj->crop(0, $diff, $diff, 0);
            } else {
                $diff = ($height-$width) / 2;
                $imageObj->crop($diff, 0, 0, $diff);
            }

            // resize image if needed
            if($resizeWidth != null) {
                $imageObj->resize($resizeWidth, $resizeWidth);
            }
            $imageObj->save( $destinationFilepath );
        }
        // return image url
        if(file_exists($destinationFilepath)) {
            return Mage::getBaseUrl('media') . $mediaPathSegment . basename($imageFilename);
        }else{
            return $imageFilename;
        }
    }
    return false;
}

No comments:

Post a Comment