0
$newimg = imagecreatefromjpeg($tempname);

Now I need to scale this image proportionally but don't know both dimensions in advance.

$newimg = imagescale($newimg, 160, auto, IMG_BICUBIC);  //doesn't work

or

$newimg = imagescale($newimg, auto, 160, IMG_BICUBIC);  // doesn't work

Is there a way to say auto or something to calculate width or height automatically.

If no, how can I calculate this?

The accepted solution here doesn't work. I doesn't keep aspect ratio.

qadenza
  • 9,025
  • 18
  • 73
  • 126
  • 2
    Possible duplicate of [Scale Image Using PHP and Maintaining Aspect Ratio](https://stackoverflow.com/questions/16774521/scale-image-using-php-and-maintaining-aspect-ratio) – Himanshu Upadhyay Apr 30 '18 at 06:40
  • @HimanshuUpadhyay, accepted solution on your link doesn't work. It doesn't keep aspect ratio. You can see in comments. – qadenza Apr 30 '18 at 06:43
  • 1
    Not sure where you got `auto`—there's no such constant in PHP and you should be getting a notice. Have you tried the documented default value, `-1`? Also, what's your PHP version? The manual clearly warns that the feature used to be broken. – Álvaro González Apr 30 '18 at 06:52
  • @ÁlvaroGonzález, my php is ver 7.2. What about `-1` pls? – qadenza Apr 30 '18 at 06:55
  • The use of -1 is on the manual page - http://php.net/manual/en/function.imagescale.php – Nigel Ren Apr 30 '18 at 07:05
  • You don't need to know the aspect ratio of the input image in advance. But you certainly know the maximum dimensions of the resized image and this is enough to compute the actual dimensions of the resized image for a given input image. – axiac Apr 30 '18 at 07:07
  • @ÁlvaroGonzález, I tried `-1` - doesn't work. Resulting image is a black square 160 x 160 – qadenza Apr 30 '18 at 07:12
  • @axiac, I don't have max but strictly `160` value. You just need to say - how to compute another dimension. – qadenza Apr 30 '18 at 07:22
  • You cannot resize to `160x160` **and** preserve the aspect ratio on the same time if the input image is not a square. You probably want to preserve the aspect ratio and resize the image to fit in a `160x160` square. – axiac Apr 30 '18 at 07:48
  • @axiac, and my question is - how to get another dimension if one dimesnion is `160`? – qadenza Apr 30 '18 at 07:58
  • You have plenty of examples in the answers of this question and in the answers of the duplicate. – axiac Apr 30 '18 at 12:21

2 Answers2

0

First of all you will have to mention al-least one dimension (either height or width) then using aspect ration of original image you can identify another. Here is a sample code which i used in my case:

$width = 160; // User-defined
$height = ''; // User-defined

$path = $uploadDir . '/' . $tempname;
$mime = getimagesize($path);

// Load original image
if($mime['mime']=='image/png') { 
    $orig_img = imagecreatefrompng($path);
}
if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' ||     $mime['mime']=='image/pjpeg') {
    $orig_img = imagecreatefromjpeg($path);
}   

// Get original image height and width
$width_orig = imagesx($orig_img);
$height_orig = imagesy($orig_img);

// Aspect ratio of original image
$aspectRatio = $width_orig / $height_orig;

// If any one dimension available then calculate other with the help of aspect-ratio of original image
if ($width == '' && $height != '') {
    $newheight = $height;
    $newwidth =  round($height * $aspectRatio);
}
if ($width != '' && $height == '') {
    $newheight = round($width / $aspectRatio);
    $newwidth = $width;
}

$newimg = imagescale($orig_img, $newwidth, $newheight, IMG_BICUBIC);
d.coder
  • 1,988
  • 16
  • 23
0

I made a function that will do what you need. I have tested this function with scaling down images and it works as intended.

This function will size an image preserving the aspect ratio to completely fit inside the dimensions that you specify. The image will also be centered.

The function also has the ability to crop. If you use the crop parameter, it will oversize the image to make sure the smallest side of the image fills the desired dimensions. It will then crop the image to fit inside the dimensions, thus completely filling the given dimensions. The image will be centered.

Here is the function:

function scaleMyImage($filePath, $newPath, $newSize, $crop = NULL){

  $img = imagecreatefromstring(file_get_contents($filePath));

  $dst_x = 0;
  $dst_y = 0;

  $width   = imagesx($img);
  $height  = imagesy($img);

  $newWidth   = $newSize;
  $newHeight  = $newSize;

  if($width < $height){  //Portrait.

    if($crop){

      $newWidth   = floor($width * ($newSize / $width));
      $newHeight  = floor($height * ($newSize / $width));
      $dst_y = (floor(($newHeight - $newSize)/2)) * -1;

    }else{

      $newWidth = floor($width * ($newSize / $height));
      $newHeight = $newSize;
      $dst_x = floor(($newSize - $newWidth)/2);

      }


  } elseif($width > $height) {  //Landscape


    if($crop){

      $newWidth   = floor($width * ($newSize / $height));
      $newHeight  = floor($height * ($newSize / $height));
      $dst_x = (floor(($newWidth - $newSize)/2)) * -1;


    }else{

      $newWidth = $newSize;
      $newHeight = floor($height * ($newSize / $width));
      $dst_y = floor(($newSize - $newHeight)/2);

      }


    }

  $finalImage = imagecreatetruecolor($newSize, $newSize);

  imagecopyresampled($finalImage, $img, $dst_x, $dst_y, 0, 0, $newWidth, $newHeight, $width, $height);

  imagejpeg($finalImage, $newPath, 60);  //Set your compression.

  imagedestroy($img);
  imagedestroy($finalImage);

}

How to use:

$newSize = 160;
$filePath = 'path/myImg.jpg';
$newPath = 'path/newImg.jpg';
$crop = 1;  //Set to NULL if you don't want to crop.

scaleMyImage($filePath, $newPath, $newSize, 1);

This should do exactly what you want with the crop parameter set to 1.

Joseph_J
  • 3,654
  • 2
  • 13
  • 22
  • you copied this code from somewhere, that's from totally different scenario. – qadenza Apr 30 '18 at 07:56
  • Why the down vote? You set the desired width and this will scale your image. I have adapted this very code and incorporated it into a class for my own site. It works great. I just put in the basics here in this function to show you how it works. Maybe I'm completely missing your question. Did you run it? It will do what you want. – Joseph_J Apr 30 '18 at 08:02
  • My question is - how to calculate `width` if `height` is `160` or vice versa ? – qadenza Apr 30 '18 at 08:09
  • Any. For example - original is `1600 x 950` and need to scale width to `250`. How to calculate new height? – qadenza Apr 30 '18 at 08:16
  • This is how you calculate the new height.. $newHeight = floor(950 * (250 / 1600)); – Joseph_J Apr 30 '18 at 08:18
  • This is how you calculate the width if you want .. $newWidth = floor(1600 * (250 / 950)); – Joseph_J Apr 30 '18 at 08:20
  • And what is $height? where did you get it? – qadenza Apr 30 '18 at 08:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/170067/discussion-between-joseph-j-and-bonaca). – Joseph_J Apr 30 '18 at 08:21
  • @bonaca Check my updated answer. It should do exactly what you want. Cheers! – Joseph_J May 01 '18 at 06:58