Okay, the reason I posted this is because I wasn\'t sure what to search for. I\'ll try to explain it as clearly as I can.
Say, I have an image sized 800x600. The box
Why not just do this with CSS and not have to use the server for any processing? There are a couple of ways to accomplish this using CSS. The Clip method is one I have used before, and a google search will bring you several results. Here is one site that covers this well
I think a simple solution with no stress and processin work would be with css:
1) Apply a class which will give you a cropped image. Do this with help of negative margin. I haven'nt used the exact margin use it as you require. 2) On hover overwrite the marging attribute, so that it will give you the real image.
css:
<style>
.crop:hover{
margin:0;
}
.crop {
margin:-100px -15px -40px -55px;
}
</style>
html:
<img class="crop" src="image.jpg" />
I use a simple PHP class which has several options for resizing. You can easily store the thumbnails via this class. As @jeroen said, you only have to do it once and they can be cached. It just requires PHP5 and GD library. Here is usage example:
// *** Include the class
include("resize-class.php");
// *** 1) Initialise / load image
$resizeObj = new resize('sample.jpg');
// *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
$resizeObj -> resizeImage(150, 150, 'crop');
// *** 3) Save image ('image-name', 'quality [int]')
$resizeObj -> saveImage('sample-resized.jpg', 100);
And this is that class:
<?php
Class resize
{
// *** Class variables
private $image;
private $width;
private $height;
private $imageResized;
function __construct($fileName)
{
// *** Open up the file
$this->image = $this->openImage($fileName);
// *** Get width and height
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
}
## --------------------------------------------------------
private function openImage($file)
{
// *** Get extension
$extension = strtolower(strrchr($file, '.'));
switch($extension)
{
case '.jpg':
case '.jpeg':
$img = @imagecreatefromjpeg($file);
break;
case '.gif':
$img = @imagecreatefromgif($file);
break;
case '.png':
$img = @imagecreatefrompng($file);
break;
default:
$img = false;
break;
}
return $img;
}
## --------------------------------------------------------
public function resizeImage($newWidth, $newHeight, $option="auto")
{
// *** Get optimal width and height - based on $option
$optionArray = $this->getDimensions($newWidth, $newHeight, $option);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
// *** Resample - create image canvas of x, y size
$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
// *** if option is 'crop', then crop too
if ($option == 'crop') {
$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
}
}
## --------------------------------------------------------
private function getDimensions($newWidth, $newHeight, $option)
{
switch ($option)
{
case 'exact':
$optimalWidth = $newWidth;
$optimalHeight= $newHeight;
break;
case 'portrait':
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
break;
case 'landscape':
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
break;
case 'auto':
$optionArray = $this->getSizeByAuto($newWidth, $newHeight);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
break;
case 'crop':
$optionArray = $this->getOptimalCrop($newWidth, $newHeight);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
break;
}
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
## --------------------------------------------------------
private function getSizeByFixedHeight($newHeight)
{
$ratio = $this->width / $this->height;
$newWidth = $newHeight * $ratio;
return $newWidth;
}
private function getSizeByFixedWidth($newWidth)
{
$ratio = $this->height / $this->width;
$newHeight = $newWidth * $ratio;
return $newHeight;
}
private function getSizeByAuto($newWidth, $newHeight)
{
if ($this->height < $this->width)
// *** Image to be resized is wider (landscape)
{
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
}
elseif ($this->height > $this->width)
// *** Image to be resized is taller (portrait)
{
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
}
else
// *** Image to be resizerd is a square
{
if ($newHeight < $newWidth) {
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
} else if ($newHeight > $newWidth) {
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
} else {
// *** Sqaure being resized to a square
$optimalWidth = $newWidth;
$optimalHeight= $newHeight;
}
}
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
## --------------------------------------------------------
private function getOptimalCrop($newWidth, $newHeight)
{
$heightRatio = $this->height / $newHeight;
$widthRatio = $this->width / $newWidth;
if ($heightRatio < $widthRatio) {
$optimalRatio = $heightRatio;
} else {
$optimalRatio = $widthRatio;
}
$optimalHeight = $this->height / $optimalRatio;
$optimalWidth = $this->width / $optimalRatio;
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}
## --------------------------------------------------------
private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
{
// *** Find center - this will be used for the crop
$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
$crop = $this->imageResized;
//imagedestroy($this->imageResized);
// *** Now crop from center to exact requested size
$this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
}
## --------------------------------------------------------
public function saveImage($savePath, $imageQuality="100")
{
// *** Get extension
$extension = strrchr($savePath, '.');
$extension = strtolower($extension);
switch($extension)
{
case '.jpg':
case '.jpeg':
if (imagetypes() & IMG_JPG) {
imagejpeg($this->imageResized, $savePath, $imageQuality);
}
break;
case '.gif':
if (imagetypes() & IMG_GIF) {
imagegif($this->imageResized, $savePath);
}
break;
case '.png':
// *** Scale quality from 0-100 to 0-9
$scaleQuality = round(($imageQuality/100) * 9);
// *** Invert quality setting as 0 is best, not 9
$invertScaleQuality = 9 - $scaleQuality;
if (imagetypes() & IMG_PNG) {
imagepng($this->imageResized, $savePath, $invertScaleQuality);
}
break;
// ... etc
default:
// *** No extension - No save.
break;
}
imagedestroy($this->imageResized);
}
## --------------------------------------------------------
}
?>
<?php
$output_width =80;
$output_height=80;
if(isset($_GET['height'])){
$output_height=$_GET['height'];
}
if(isset($_GET['width'])){
$output_width=$_GET['width'];
}
$path = ( (isset($_REQUEST['path']))? $_REQUEST['path'] : "");
//echo $path;exit;
$size_arr = getimagesize($path);
if ($size_arr[2]==IMAGETYPE_GIF)
$image = imagecreatefromgif($path);
else if ($size_arr[2]==IMAGETYPE_JPEG)
$image = imagecreatefromjpeg($path);
else if ($size_arr[2]==IMAGETYPE_PNG)
$image = imagecreatefrompng($path);
else
die_default_image();
$tmpname = tempnam( sys_get_temp_dir() , "phptmp");
resize_image($tmpname, $image, $size_arr, $output_width, $output_height);
header('Content-Type: image/jpg');
header('Content-Disposition: inline; filename="'.basename($path).'"');
echo file_get_contents( $tmpname );
unlink( $tmpname );
die('');
function die_default_image()
{
//43byte 1x1 transparent pixel gif
header("content-type: image/gif");
echo base64_decode("R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==");
}
function resize_image($thumbname, $image, $size_arr, $max_width, $max_height)//maintain aspect ratio
{
$width = $max_width;
$height = $max_height;
list($width_orig, $height_orig, $img_type) = $size_arr;
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig) {
$width = floor($height*$ratio_orig);
} else {
$height = floor($width/$ratio_orig);
}
// Resample
$tempimg = imagecreatetruecolor($width, $height);
imagecopyresampled($tempimg, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagejpeg($tempimg, $thumbname, 80);
}
if (!function_exists('sys_get_temp_dir')) {
function sys_get_temp_dir() {
if (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); }
if (!empty($_ENV['TMPDIR'])) { return realpath( $_ENV['TMPDIR']); }
if (!empty($_ENV['TEMP'])) { return realpath( $_ENV['TEMP']); }
$tempfile=tempnam(uniqid(rand(),TRUE),'');
if (file_exists($tempfile)) {
unlink($tempfile);
return realpath(dirname($tempfile));
}
}
}
?>
Save the file as imageresize.php and put this file in your image folder and just use the code like this to show image
<img src="<?=base_url().'uploads/imageresize.php?path='.$image."&width=150 &height=150";?>" />
you can use this code to show images in different sizes.
I have a shell script in place that does exactly what you need with ImageMagick:
#!/bin/sh
SOURCE='/path/to/img'
FILE='myfile.jpg'
convert $SOURCE/$FILE -thumbnail 150x150^\> -quality 85% \
-gravity center -extent 150x150 ${SOURCE}150/$FILE
^
after 150x150
is essential! -thumbnail
option strips all meta-information except for color profiles and is very fast.-gravity center -extent 150x150
) - exactly what you want. -quality 85%
which should be plenty while reducing file size a lot.img
directory and write the thumbnail with the same filename to a img150
directory right next to it.Experiment for best results.
I had help from:
http://www.imagemagick.org/Usage/files/
http://www.imagemagick.org/Usage/resize/
http://www.imagemagick.org/script/command-line-options.php#thumbnail
This is exactly you´re looking for, and one step futher, caching thumbs:
Check http://phpthumb.gxdlabs.com/
You can use this script as script.php?img=image.jpg&size=100, in this case, they are on the same folder of the script.
<?php
require_once '/path/to/ThumbLib.inc.php';
$filename = $_GET['img'];
$path = "/upload/item/";
$thumb = $_GET['size'];
// Just let specific values
$sizeThumb = array('20','40','50','80','100','120','150');
if(in_array($thumb,$sizeThumb)){
$maxWidth = $thumb;
$maxHeight = $thumb;
} else { header('Status: 404 Not Found'); die; }
$pathUrl = _ROOT_FOLDER.'/thumbs/autothumb-'.$thumb.'-'.$filename;
if(!file_exists(_ROOT_FOLDER.$path.$filename)) { header('Status: 404 Not Found'); die; }
if(!file_exists($pathUrl) ){
$max = PhpThumbFactory::create(_ROOT_FOLDER.$path.$filename);
$max->adaptiveResize($maxWidth,$maxHeight)->save($pathUrl);
}
header('Content-type: image/jpeg');
readfile($pathUrl);
?>