Forum Moderators: coopster
I have a function that creates a thumbnail representation of a real file, what I would like to do I be able to create a thumbnail with a canvas size of exactly 100 x 100 px and then be able the vertically and horizontally align the image in its container.
So far I have something like this:
// I create the image from a file
$img = Imagecreatefromjpeg($filename);// Create the canvas
$img_n = imagecreatetruecolor($width, $height);// Merge the file with the canvas
imagecopyresampled($img_n, $img, 0, 0, $xoffset, $yoffset, $width, $height, $org_width, $org_height);
I hope this makes sense, I would really appreciate some help on this.
Thank you all for your time.
Del
$imginfo = getimagesize($imgfiletmp);
$width = $imginfo[0];
$height = $imginfo[1];
then later
if ($width > $height) {
$orient = 'wide';
$bigdim = $width;
} else {
$orient = 'tall';
$bigdim = $height;
} then later
if ($bigdim > 600) {
$longside = 600;
$shortside = 0;
if ($orient == 'wide'){
$shortside = round($longside/($width/$height));
$dest_x = $longside;
$dest_y = $shortside;
} else {
$shortside = round($longside/($height/$width));
$dest_x = $shortside;
$dest_y = $longside;
} I am using 600 but you can swap that to whatever you want
and finally
$target_pic = imagecopyresized($target_id, $source_id, 0, 0, 0, 0, $dest_x, $dest_y, $width, $height);
the same rules would apply, obviously your last line would be different but the ratio stuff should be fine.
This can be corrected by copying a square section of the original, rather than the whole image. I tested this and it works. If the pic is rectangle, it grabs the largest square portion from the center of the image.
<?php
$filename = 'image.jpg';
list($width, $height) = getimagesize($filename);
//now assign the coords to snip from the orig
if ($width > $height) {
$src_w = $src_h = $height;
$src_y = 0;
$src_x = round(($width - $height) / 2);
} else {
$src_w = $src_h = $width;
$src_x = 0;
$src_y = round(($height - $width) / 2);
}
//now create and resample
$dst_image = imagecreatetruecolor(100, 100);
$src_image = imagecreatefromjpeg($filename);
imagecopyresampled ( $dst_image, $src_image, 0, 0, $src_x, $src_y, 100, 100, $src_w, $src_h );
header('Content-type: image/jpeg');
imagejpeg($dst_image, null, 100);
?>
I don't want the image to crop, i want it to fix in the containing image resource.
For example:
I have an image that's 400px / 200px and i want to fit this image into the 100px / 100px container, without cropping the image but by scaling the image.
So what i should be doing in reducing the size of the image in proportion using the larger image as the marker. Along with this i would like the image to be placed centre of the container no matter the width or height.
I don't want to crop the image, it's for a listing page, this is why i need it to be compact but viewable at the same time.
If i haven't made much more sense please let me know.
Thank you once again.
Del
<?php
$filename = 'image.jpg';
list($width, $height) = getimagesize($filename);
//now create and resample
$dst_image = imagecreatetruecolor(100, 100);
$src_image = imagecreatefromjpeg($filename);
imagecopyresampled ( $dst_image, $src_image, 0, 0, 0, 0, 100, 100, $width, $height );
header('Content-type: image/jpeg');
imagejpeg($dst_image, null, 100);
?>
<?php
$filename = $_SERVER['DOCUMENT_ROOT'] . '/presentations/images/816.jpg';
list($width, $height) = getimagesize($filename);
if ($width > $height) {
$dst_w = 100;
$dst_h = round((100 / $width) * $height);
$dst_x = 0;
$dst_y = round((100 - $dst_h) / 2);
} else {
$dst_w = round((100 / $height) * $width);
$dst_h = 100;
$dst_y = 0;
$dst_x = round((100 - $dst_w) / 2);
}
//now create and resample
$dst_image = imagecreatetruecolor(100, 100);
$background = imagecolorallocate($dst_image, 250, 250, 250);
imagefill($dst_image, 0, 0, $background);
$src_image = imagecreatefromjpeg($filename);
imagecopyresampled ( $dst_image, $src_image, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $width, $height );
header('Content-type: image/jpeg');
imagejpeg($dst_image, null, 100);
?>
[edited by: Birdman at 6:10 pm (utc) on Feb. 24, 2007]
I only managed to play with the code this morning and i am interested in finding out the following.
How could i make the image only resize if the new image size is smaller then the original and still keep the positioning centered verticaly and horizontally?
I assume this would be done by comparing the original height with the new height and then setting the positions but i didn't get very far.
Any help would be great.
Thank you
Del
Once again, thanks for all the help.
My pleasure!
How could i make the image only resize if the new image size is smaller then the original and still keep the positioning centered verticaly and horizontally?
So you still want to create a new image and position it on a 100x100 canvas even if it is smaller than 100px? Also, are you actually serving these images on the fly or are you planning on saving them to files?
Birdman, the image master
Ha! NOT! I do have fun with GD though :)
I have some images that are like 65px / 50px and i don't want them to enlarge to 100px / 100px in the box so if they are not bigger then the specified height / width then i want them to stay at the original size.
I hope that makes sense.
Thanks again.
Del
Thank you.
<?php
$filename = $_SERVER['DOCUMENT_ROOT'] . '/presentations/images/816.jpg';
list($width, $height) = getimagesize($filename);
if ($width < 100 && $height < 100){
$dst_w = $width;
$dst_h = $height;
$dst_x = round((100 - $dst_w) / 2);
$dst_y = round((100 - $dst_h) / 2);
} else {
if ($width > $height) {
$dst_w = 100;
$dst_h = round((100 / $width) * $height);
$dst_x = 0;
$dst_y = round((100 - $dst_h) / 2);
} else {
$dst_w = round((100 / $height) * $width);
$dst_h = 100;
$dst_y = 0;
$dst_x = round((100 - $dst_w) / 2);
}
}
//now create and resample
$dst_image = imagecreatetruecolor(100, 100);
$background = imagecolorallocate($dst_image, 250, 250, 250);
imagefill($dst_image, 0, 0, $background);
$src_image = imagecreatefromjpeg($filename);
imagecopyresampled ( $dst_image, $src_image, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $width, $height );
header('Content-type: image/jpeg');
imagejpeg($dst_image, null, 100);
?>
This one is not tested :)
$dst_x is the x(from the left) position where you want your image to start on the 100x100 canvas.
$dst_y is the y(from the top) position where you want your image to start on the 100x100 canvas.
After you have determined the scaled dimensions or decided that the image doesn't need scaling, you calculate the x and y start points by subtracting the image size from the canvas size.
eg. your image is already smaller (60 x 40)
Get the difference of image and canvas for width and height
100-60 = 40 / 2 = 20
100-40 = 60 / 2 = 30
now you have your starting points for x(20 from left) and y(30 from top)
That's exactly what i was looking for.
Thank you once again, the images i have resized look amazing and the functionality works a treat.
Once again, much appreciated.
Del
After you resize to fit within a container, you subtract the short from the long, and divide by 2 to give the offset (already explained above, so this is redundant).
To wit:
$offset = intval ((100 - $short_len) / 2); The resizing is merely keeping an aspect ratio (
$aspect = $x_size/$y_size), and multiplying or dividing that by 100 to get the short side. If the aspect is greater than 1, then the image is wide, and the offset is on the Y-axis (from top), if less than 1, it is tall.
This makes thumbnails 150 x 100. However it does a couple of extra tricks that I wanted.
If image is smaller than 150 x 100 it retains the size.
If image is almost square (say 600 x 590), the problem with the script and my not-square thumbs was that it made the height too big by keeping in it proportion. i.e. when width became 150, height was around 148.
I have added some code so that if the height is > 100 after resizing, then no matter what the width, it resizes using the height as the constraining factor.
There is some debug code that comes in handy for "those special moments"
Hope it helps someone.
if ($width > $height) {
if($width < 150){
$debug=1;
$thumb_w = $width;
$thumb_h = $height;
$dst_x = 0;
$dst_y = round(($dst_w - $dst_h) / 2);
}
else{
$debug=2;
$thumb_w = 150;
$thumb_h = round((150 / $width) * $height);
$dst_x = 0;
$dst_y = round((150 - $dst_h) / 2);
//if it is almost square we need to make width a bit smaller - treat it as if height is the bigger side
if($thumb_h> 100){
$debug=5;
$thumb_w = round((100 / $height) * $width);
$thumb_h = 100;
$dst_y = 0;
$dst_x = round((100 - $dst_w) / 2);
}
}
} else {
if($height < 100){
$debug=3;
$thumb_h = $height;
$thumb_w = width;
$dst_y = 0;
$dst_x = round(($dst_h - $dst_w) / 2);
}
else{
$debug=4;
$thumb_w = round((100 / $height) * $width);
$thumb_h = 100;
$dst_y = 0;
$dst_x = round((100 - $dst_w) / 2);
//if it is almost square we need to make width a bit smaller - treat it as if width is the bigger side
if($thumb_h> 100){
$debug=6;
$thumb_w = 150;
$thumb_h = round((150 / $width) * $height);
$dst_x = 0;
$dst_y = round((150 - $dst_h) / 2);
}
}
}
//echo " core.php line 163<br>d= " . $debug . " w = " . $thumb_w . " h = " . $thumb_h . " or = " . $width . " oh = " . $height; exit;
...sigh...sorry, I give up on making it look good
[edited by: xMicrobex at 8:03 am (utc) on May 14, 2008]