Image Cropping refers to the removal of the outer parts of an image to improve framing, accentuate subject matter or change aspect ratio. In this article I will demonstrate a technique that combines resizing and cropping to fit an image in given dimensions. You can, for example, use this technique to generate square thumbnails for images with arbitrary dimensions and aspect-ratio.
The following diagrams demonstrate what I am trying to accomplish here. Source images having arbitrary dimensions and aspect ratio are intelligently resized to desired dimensions and aspect ratio without distortion.
Example 1: When aspect ratios are same
Example 2: When source image is wider
Example 3: When source image is taller
This is accomplished by resizing the image such that:
- the original aspect ratio is maintained
- one of the dimensions is equal to the desired size
- the other dimension is equal to or greater than the desired size
Once resized, it is fairly straight-forward to calculate the cropping parameters.
ASP (Classic) Implementation
Unfortunately, classical ASP does not provide native methods for handling file uploads and processing images. Therefore, we will have to rely on server components. The example will demonstrate how you can utilize the following two commercially available components for this task:
- Persits Software AspUpload
- Persits Software AspJpeg
The HTML Form
The HTML form posts the file to the processing script. You may notice the use of enctype="multipart/form-data"
in the following form.
<form action="image-crop-demo.asp" method="post" enctype="multipart/form-data"> Upload an image for processing<br> <input type="file" name="Image1"><br> <input type="submit" value="Upload"> </form>
The ASP Code
<%@ language="vbscript" %> <% option explicit ' ' Crop-to-fit ASPJPEG ' http://salman-w.blogspot.com/2009/04/crop-to-fit-image-using-aspphp.html ' ' Resize and center crop an arbitrary size image to fixed width and height ' using Persits Software AspJpeg ' const DESIRED_IMAGE_WIDTH = 150 const DESIRED_IMAGE_HEIGHT = 150 dim oUpload set oUpload = Server.CreateObject("PERSITS.UPLOAD") ' ' Ideally, you should set the properties for ASPUPLOAD component here ' oUpload.Save dim oFile set oFile = oUpload.Files("Image1") dim oJpeg set oJpeg = Server.CreateObject("PERSITS.JPEG") ' ' Ideally, you should set the properties for PERSITS.JPEG component here ' ' This example requires that PreserveAspectRatio is set to FALSE ' Otherwise you may notice round-off errors when ASPJPEG resizes the image ' oJpeg.PreserveAspectRatio = false oJpeg.OpenBinary(oFile.Binary) dim SourceAspectRatio dim DesiredAspectRatio SourceAspectRatio = oJpeg.Width / oJpeg.Height DesiredAspectRatio = DESIRED_IMAGE_WIDTH / DESIRED_IMAGE_HEIGHT if SourceAspectRatio > DesiredAspectRatio then ' ' Triggered when source image is wider ' oJpeg.Height = DESIRED_IMAGE_HEIGHT oJpeg.Width = DESIRED_IMAGE_HEIGHT * SourceAspectRatio else ' ' Triggered otherwise (i.e. source image is similar or taller) ' oJpeg.Width = DESIRED_IMAGE_WIDTH oJpeg.Height = DESIRED_IMAGE_WIDTH / SourceAspectRatio end if dim X0 dim Y0 dim X1 dim Y1 ' ' Crop the image keeping the CENTER part intact ' X0 = (oJpeg.Width - DESIRED_IMAGE_WIDTH) / 2 Y0 = (oJpeg.Height - DESIRED_IMAGE_HEIGHT) / 2 X1 = X0 + DESIRED_IMAGE_WIDTH Y1 = Y0 + DESIRED_IMAGE_HEIGHT oJpeg.Crop X0, Y0, X1, Y1 oJpeg.SendBinary %>
PHP+GD Library Implementation
The code differs from the resize image using php and gd library example I posted earlier. The main difference is in the way the resize dimensions are calculated. And then there is an additional step that crops the resized image.
The HTML Form
The HTML form remains exactly the same as above except the action attribute.
<form action="image-crop-demo.php" method="post" enctype="multipart/form-data"> Upload an image for processing<br> <input type="file" name="Image1"><br> <input type="submit" value="Upload"> </form>
The PHP Code
<?php /* * Crop-to-fit PHP-GD * http://salman-w.blogspot.com/2009/04/crop-to-fit-image-using-aspphp.html * * Resize and center crop an arbitrary size image to fixed width and height * e.g. convert a large portrait/landscape image to a small square thumbnail */ define('DESIRED_IMAGE_WIDTH', 150); define('DESIRED_IMAGE_HEIGHT', 150); $source_path = $_FILES['Image1']['tmp_name']; /* * Add file validation code here */ list($source_width, $source_height, $source_type) = getimagesize($source_path); switch ($source_type) { case IMAGETYPE_GIF: $source_gdim = imagecreatefromgif($source_path); break; case IMAGETYPE_JPEG: $source_gdim = imagecreatefromjpeg($source_path); break; case IMAGETYPE_PNG: $source_gdim = imagecreatefrompng($source_path); break; } $source_aspect_ratio = $source_width / $source_height; $desired_aspect_ratio = DESIRED_IMAGE_WIDTH / DESIRED_IMAGE_HEIGHT; if ($source_aspect_ratio > $desired_aspect_ratio) { /* * Triggered when source image is wider */ $temp_height = DESIRED_IMAGE_HEIGHT; $temp_width = ( int ) (DESIRED_IMAGE_HEIGHT * $source_aspect_ratio); } else { /* * Triggered otherwise (i.e. source image is similar or taller) */ $temp_width = DESIRED_IMAGE_WIDTH; $temp_height = ( int ) (DESIRED_IMAGE_WIDTH / $source_aspect_ratio); } /* * Resize the image into a temporary GD image */ $temp_gdim = imagecreatetruecolor($temp_width, $temp_height); imagecopyresampled( $temp_gdim, $source_gdim, 0, 0, 0, 0, $temp_width, $temp_height, $source_width, $source_height ); /* * Copy cropped region from temporary image into the desired GD image */ $x0 = ($temp_width - DESIRED_IMAGE_WIDTH) / 2; $y0 = ($temp_height - DESIRED_IMAGE_HEIGHT) / 2; $desired_gdim = imagecreatetruecolor(DESIRED_IMAGE_WIDTH, DESIRED_IMAGE_HEIGHT); imagecopy( $desired_gdim, $temp_gdim, 0, 0, $x0, $y0, DESIRED_IMAGE_WIDTH, DESIRED_IMAGE_HEIGHT ); /* * Render the image * Alternatively, you can save the image in file-system or database */ header('Content-type: image/jpeg'); imagejpeg($desired_gdim); /* * Add clean-up code here */ ?>
Example Output
Original Image
ASPJPEG Output
PHP+GD Output