I want to resize the images to fixed width and height (i.e. 150px). However, theres a problem, if there is lots of difference in height and width of original photo (for example, panoramic photo), the resized thumbnail looks bad. Is there any any smart solution to resize the photos to a fixed width and height? For example, please have a look at this
image:
Here's my code:
<?php
$params = getimagesize($tempFile);
$width = $params[0];
$height = $params[1];
$newwidth=150;
$newheight= 150;
$tmp=imagecreatetruecolor($newwidth,$newheight);
imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
imagejpeg($tmp,$img_name,80);
imagedestroy($src);
imagedestroy($tmp);
?>
Is there any smart way to resize the images in smart way?
Thanks.
There's a smart solution, it's called Seam Carving, and if your server supports ImageMagick, you do it like this:
<?php
$im = new Imagick( 'image.jpg' );
$im->liquidRescaleImage( 600, 100, 3, 25 );
header( 'Content-Type: image/jpg' );
echo $im;
?>
Or alternatively, if it doesn't support, use exec() (carefully) in order to pass image as an argument to executable which can perform seam carving.
BTW it looks like twitpic just crop's the squared image extract.
In one of my previous projects I used following code:
if ($image->width > $image->height){
//crop image in proportions 4/3, then resize to 500x300 (or proportionally lower resolution),
//sharp it a little and decrease quality.
//I used one of the Yii framework extensions.
$image->crop($image->width, $image->width/4*3)->resize(500, 300, Image::WIDTH)->sharpen(15)->quality(75);
}
It looks like twitpic is finding out how long the short axis is, then takes a square centered on the original image with sides equal to the short axis length, then shrinking that down to 150x150.
Not, resmaple, get only center 150x150 pixels.
You will need to calculate the appropriate coordinates for the original area you want to copy:
imagecopyresampled($tmp,$src,0,0,[THIS VALUE],[THIS VALUE],$newwidth,$newheight, [THIS VALUE],[THIS VALUE]);
As of now, you take the area from 0,0 (x,y) to width,height (x,y) of the original area and try to cramp it into 150x150.
you will need to calculate which of width and height that is the "biggest" and crop that and make sure that the ratio is the same as your resulting image (in your case, ratio is 1.0 because of 150x150).
In your example, where width is 1050 and height is 317 pixels so you want a portion of the original image that is 317x317 (ratio 1.0), you need to:
subtract 317 from 1050 = 733; // this is the excessive area for both sides
divide by 2 =~ 366; // to get the excessive area for one side
Now, use first x coordinate 366, to start 366 pixels from the left.
Use second x coordinate 1050 - 366 start 366 pixels from the right.
So your example should be (just guessing here):
imagecopyresampled($tmp,$src,0,0,366,0,$newwidth,$newheight, $width - 366, 0);
You will of course need some logic in order to calculate this correctly for any other size.
Related
I'm trying to get an image and crop it then resize it to a thumbnail using PHPThumb. I want to crop the left side, right side, top and bottom in similar percentages. For example, crop 30% from left and 30% from right side; crop 40% from top bottomwards and 40% from bottom upwards How can I go about it. All I see in the manual is passing the SX value which I suppose only crops it mathematically from the bottom left(where x=0). I need to be able to crop from both sides towards the centre of the image. I hope you get what I mean.
I am using PHPThumb and not something custom since it has good JPEG compression when resizing, therefore the images have the clarity of the originals.
IMPORTANT EDIT: I have been notified that such a feature is not available in PHPThumb, anybody know of any such thumbnaik generator with the above cropping functions?
You could use Imagemagick -shave ( http://www.imagemagick.org/script/command-line-options.php#shave )but would need to calculate the pixels from the percentages first.
Untested code:
$size = getimagesize($input);
$horizontal = round( ($size[0]x0.3), 0);
$vertical = round( $size[1]x0.4), 0);
$cmd = "$input -shave {$horizontal}x{$vertical}";
exec("convert $cmd output.jpg");
While i was doing some image processing, i found out that GD and Imagick in PHP does not resize image to color pixel identical level, which in most cases, were not needed.
Now in case, i need a image from whatever dimension to scale to 256*256
To make sure the TEST results are consistent, i used a 256*256 image and resize it to it's own size.
what i've attempted:
imagecopyresized($new, $img, 0, 0, $x, 0, $width, $height, $w, $h); //256 , 256
and
$compression_type = imagick::COMPRESSION_NO;
$images_ima = new Imagick($image_path); //$image_path = path to image...
$images_ima->setImageCompression($compression_type);
$images_ima->setImageCompressionQuality(100);
$images_ima->sampleImage($X_SIZE,$Y_SIZE); // 256 ,256
$images_ima->writeImages($dest_path, true); //destination path
none of them worked, if i compare the output with the original image, it will look something like this:
it looks like the functions i've used are resampling the image since the variations in the RGB value between both image are small
i can achieve pixel to pixel identical resizing from 256*256 to 256*256 in photoshop, OSX preview, and even Pixelformer.
i was wondering how can that be done i PHP?
Since your image format (jpeg - assumed from 100 quality setting) is a lossy format you won't get a lossless throughput this way as you're recompressing the image.
You should try to detect image dimensions and use the original image if the dimensions are already correct.
When you don't change the dimensions (original dimensions = dimensions after resizing) in Photoshop or OSX preview they won't recompress the image, that's why you won't see any change.
I am trying to accomplish this task for 2 days, read various stuffs online but still can't find out what is happen, also read all here at SO about similar problems but nothing.
I have image 400x400 and want to generate 120x120 using php gd. using this code:
$image_p = imagecreatetruecolor(120,120);
$image = imagecreatefromstring($X_IMAGE);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, 120, 120, 400, 400);
// RETURN
header('Content-Type: image/jpeg');
imagejpeg($image_p, null, 70);
//destroy...
$X_IMAGE is 400x400 JPG that is stored as string.
All images are generated in 120x120 but most of them have some BLACK rectangle at bottom at some pictures it is larger on some it is smaller but 50% of images are with that square. So all are VISIBLE, just some part of image is covered with that black color. What would be solution for my problem? All source images are JPG and also those 120x120 that I need are JPG as you can see...
The problem is that your original image is not a square! You pass 400x400 to imagecopyresampled, but the height of the original image maybe is not 400px!
In the image you posted, for example, you have a not-squared original image. When you tell PHP to resample a square on anther image resource, you will resample the image plus a non-existent rectangle at the bottom.
The solution depends on what you want to output.
Do you want a scaled image that keeps ratio? For example, from 400x300 to 120x90.
Or a scaled image that not keeps ratio? For example, from 400x300 to a distorted 120x120?
Or a cropped thumbnail? 400x300 to a 120x120 with left and right parts trimmed out a little?
Do you want to replace the black rectangle with a white one, so fill the resampled image in that way?
I want to resize an image to a max width. So I don't care about the height of the image, but I just want to always resize it to a specific width.
I'm certain I've done this before I just can't remember how I did it now.
Seems this is the way it is done, noting that width is the first parameter.
convert -resize '100' image.png
For anyone else wondering about height, then you would do this:
convert -resize 'x100' image.png
Source: http://www.imagemagick.org/script/command-line-processing.php
Edit (Nov 2014): Note that in the latest versions of ImageMagick you can no longer use quotes around the values as per Kevin Labécot's comment.
Your question is ambiguous. Your titles asks to resize an image to a max width, but then you seem to say you want to resize the image to a specific width.
If you want to resize something to a max width of 600px (ie, any image with a width of less than 600px will be unaffected), use:
convert original_image.jpg -resize 600x\> result_image.jpg
Or, to directly modify the original image:
mogrify -resize 600x\> original_image.jpg
If you'd like max height rather than max width:
convert original_image.jpg -resize x600\> result_image.jpg
Are you just chasing the math to work out the correct aspect ratio?
$new_width = 400; // config
$image_width = 480; // loaded from image
$image_height = 786; // loaded from image
$new_height = $new_width * ($image_height / $image_width);
echo "$image_width x $image_height becomes $new_width x $new_height";
The way to resize to a given width in ImageMagick is:
convert image -resize Wx result
or just
convert image -resize W result
where W=width and is provided, but H=height is not included
See https://imagemagick.org/script/command-line-processing.php#geometry
HEllo,
I am trying to rotate a circular image around the center and then cut off the sides. I see the imagerotate function, but it does not seem to rotate about centre.
Anyone have any suggestions?
Thank you.
Update: Since it is a circle, I want to cut off the edges and keep my circle in the same dimensions.
The documentation says that it does rotate around the center.
Unfortunately it also says that it will scale the image so that it still fits. That means that whatever you do this function will change the size of your internal circular image.
You could (relatively easily) calculate how much scaling down will happen and then prescale the image up appropriately beforehand.
If you have the PHP "ImageMagick" functions available you can use those instead - they apparently don't scale the image.
I faced successfully that problem with the following code
$width_before = imagesx($img1);
$height_before = imagesy($img1);
$img1 = imagerotate($img1, $angle, $mycolor);
//but imagerotate scales, so we clip to the original size
$img2 = #imagecreatetruecolor($width_before, $height_before);
$new_width = imagesx($img1); // whese dimensions are
$new_height = imagesy($img1);// the scaled ones (by imagerotate)
imagecopyresampled(
$img2, $img1,
0, 0,
($new_width-$width_before)/2,
($new_height-$height_before)/2,
$width_before,
$height_before,
$width_before,
$height_before
);
$img1 = $img2;
// now img1 is center rotated and maintains original size
Hope it helps.
Bye
According to the PHP manual imagerotate() page:
The center of rotation is the center
of the image, and the rotated image is
scaled down so that the whole rotated
image fits in the destination image -
the edges are not clipped.
Perhaps the visible center of the image is not the actual center?