Reputation: 165
I am trying to make thumbnails of images I have lying around. They have all kinds of resolutions, but I want to create thumbnails which are 225 by 150 in size. What I have been trying to do, is to directly transform either the width or height (depending on what works best) and use a centered part of the original image. For some images it works fine, but for others it fails horribly.
The direct logic between what I want to do:
if the width is fine, and the height is big:
use the width as is
calculate height - the height which would go with width for the thumbnail ratio.
else
use the height as is
calculate width - the width which would go with height for the thumbnail ratio
This would give the part of the image that is not used. It is used as x and y offsets. I also reduce the size of the part of the image being used.
I have a function I use for thumbnails, but I am unsure of the relation between the ratio and the actual width and height:
function shrinkImage( $owidth, $oheight, $filename, $newFile ) {
if ( ($img_info = getimagesize( $filename ) ) === FALSE) {
die("Image not found or not an image");
}
switch ( $img_info[2] ) {
case IMAGETYPE_GIF :
$image = imagecreatefromgif( $filename);
break;
case IMAGETYPE_JPEG :
$image = imagecreatefromjpeg( $filename );
break;
case IMAGETYPE_PNG :
$image = imagecreatefrompng( $filename );
break;
default :
die( "Unknown filetype" );
}
$thumb_width = 225;
$thumb_height = 150;
if( ($oheight/$thumb_height) < ($owidth/$thumb_width) ) {
$y = 0;
$x = $owidth - ($oheight * $thumb_width / $thumb_height);
} else {
$x = 0;
$y = $oheight - (($owidth * $thumb_height) / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
imagecopyresampled( $thumb, $image, 0, 0, $x, $y, $thumb_width, $thumb_height, $owidth - ($x * 2), $oheight - ($y * 2));
switch ( $img_info[2] ) {
case IMAGETYPE_GIF :
imagegif( $thumb, $newFile );
break;
case IMAGETYPE_JPEG :
imagejpeg( $thumb, $newFile, 100 );
break;
case IMAGETYPE_PNG :
imagepng($thumb, $newFile, 0 );
break;
default :
die("Unknown filetype");
}
return True;
}
Here is an example of an original vs a cropped image:
This is not the kind of thumbnails my code produces, but an example of what I want it to do.
Edit:
if( ($oheight/$thumb_height) < ($owidth/$thumb_width) ) {
$y = 0;
$x = $owidth - ($oheight * $thumb_width / $thumb_height);
} else {
$x = 0;
$y = $oheight - ($owidth * $thumb_height / $thumb_width * 2);
}
Works for tall images, and some normal images, but creates some horrible lines for wide images.
Upvotes: 0
Views: 1236
Reputation: 165
After digging up some long lost mathematics knowledge, I found a working solution:
$thumb_width = 225;
$thumb_height = 150;
if( ($owidth/$thumb_width) > ($oheight/$thumb_height) ) {
$y = 0;
$x = $owidth - ( ($oheight * $thumb_width) / $thumb_height);
} else {
$x = 0;
$y = $oheight - ( ($owidth * $thumb_height) / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
imagecopyresampled( $thumb, $image, 0, 0, $x/2, $y/2, $thumb_width, $thumb_height, $owidth - $x, $oheight - $y);
Upvotes: 2