-2

I'm re-sizing the images uploaded by user to some specific size(i.e. specific width and height). I want to make the uploaded images of dimension 940 px * 370 px. But while doing so I don't want to affect the quality of image originally uploaded by user at all.

The issue I'm facing with my code is the image dimensions are getting reduced to the specified dimensions but the quality of image is severely getting affected. The uploaded images are getting shrink.

I'm not getting how should I keep the quality of uploaded image intact

For achieving this functionality I've written following code.

HTML Code :

<html>
  <body>
    <form action="upload_file.php" method="post" enctype="multipart/form-data">
      <label for="file">Filename:</label>
      <input type="file" name="file" id="file"><br>
      <input type="submit" name="submit" value="Submit">
    </form>
  </body>
</html>

PHP Code :

<?php
  $allowedExts = array("gif", "jpeg", "jpg", "png");
  $temp = explode(".", $_FILES["file"]["name"]);
  $extension = end($temp);

  if ((($_FILES["file"]["type"] == "image/gif")
    || ($_FILES["file"]["type"] == "image/jpeg")
    || ($_FILES["file"]["type"] == "image/jpg")
    || ($_FILES["file"]["type"] == "image/pjpeg")
    || ($_FILES["file"]["type"] == "image/x-png")
    || ($_FILES["file"]["type"] == "image/png"))
    && ($_FILES["file"]["size"] < 5242880)
    && in_array($extension, $allowedExts)) {
      if ($_FILES["file"]["error"] > 0) {
        echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
      } else {
        echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        echo "Type: " . $_FILES["file"]["type"] . "<br>";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";
        if (file_exists("upload/" . $_FILES["file"]["name"])) {
          echo $_FILES["file"]["name"] . " already exists. ";
        } else {
          //move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);

          //Store the name of the temporary copy of the file stored on the server
          $images = $_FILES["file"]["tmp_name"];         

          /*Create a new file name for uploaded image file :
           *prepend the string "upload" to it's original file name
          */
          $new_images = "upload".$_FILES["file"]["name"];

          //Copies a file contents from one file to another
          //copy($_FILES["file"]["tmp_name"],"upload/".$_FILES["file"]["name"]);

          $width = 940;

          //Determine the size of a given image file and return the dimensions along with the file type 
          $size=GetimageSize($images);

          //$height=round($width*$size[1]/$size[0]);

          $height = 370;

          //Create a new image from file or URL & returns an image identifier representing the image obtained from the given filename.
          $images_orig = ImageCreateFromJPEG($images);

          //Get image width of originally uploaded image
          $photoX = ImagesX($images_orig);

          //Get image height of originally uploaded image
          $photoY = ImagesY($images_orig);

          //Create a new true color image & returns an image identifier representing a black image of the specified size.
          $images_fin = ImageCreateTrueColor($width, $height);

          /*Copy and resize part of an image with resampling
           *copies a rectangular portion of one image to another image, 
           *smoothly interpolating pixel values so that, in particular, 
           *reducing the size of an image still retains a great deal of clarity. 
          */
          ImageCopyResampled($images_fin, $images_orig, 0, 0, 0, 0, $width+1, $height+1, $photoX, $photoY);

          /*Output image to browser or file
           *creates a JPEG file from the given image.
          */  
          ImageJPEG($images_fin,"upload/".$new_images);

          /*Destroy an image
           *frees any memory associated with image image.  
          */
          ImageDestroy($images_orig);
          ImageDestroy($images_fin);

          echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
        }
      }
    } else {
      echo "Invalid file";
    }
?>

It would be immensely helpful for me if someone could help me in this regard.

Thanks in advance.

For more clear understanding of the issue I'm facing I'm attaching the original image and the modified image using PHP code:

Original image is as follows: enter image description here

The image after uploading the server(i.e. the affected image) is as follows: enter image description here

PHPLover
  • 1
  • 51
  • 158
  • 311
  • Could you show an example of an uploaded image and resized result? The problem could be either the resizing or JPEG compression. – Overv Oct 05 '14 at 13:53
  • Default JPEG quality is set to 75. Set the `$quality` parameter of `imagejpeg` to something higher than the default value. `bool imagejpeg ( resource $image [, string $filename [, int $quality ]] )` – Kevin Labécot Oct 05 '14 at 13:54
  • @Overv:As per your suggestion I've added both the images to my question. Please check. – PHPLover Oct 05 '14 at 13:57
  • @user2839497 There are two solutions to this problem. You can either resize the image so that it fits inside your width and height, or you can crop the image so that it fits. The difference is that with the first solution, the result may not have the dimensions 940x370, but the width and height will be below that. Which solution do you want? – Overv Oct 05 '14 at 14:02
  • @Overv:I want the effective one. The one which would be easier and effective. In fact I want to make the resolution 940*370 but the quality of image shouldn't get affected in any sense. That's the my ultimate goal. If possible you can provide both. – PHPLover Oct 05 '14 at 14:03
  • @user2839497 Let me put it more clearly then. Would you prefer parts of the images (e.g. the sides) missing or the image not filling up 940x370? – Overv Oct 05 '14 at 14:04
  • @Overv:No, I don't want to miss any part of uploaded image but still I want to reduce it's resolution without affecting it's original quality. – PHPLover Oct 05 '14 at 14:06

1 Answers1

1

Instead of always scaling the image to 940x370, you should scale it to preserve the aspect ratio. You can do that like this:

$scaleX = $width / $photoX;
$scaleY = $height / $photoY;
$scale = min($scaleX, $scaleY);

$scaleW = $scale * $photoX;
$scaleH = $scale * $photoY;

$images_fin = ImageCreateTrueColor($width, $height);

$background = ImageColorAllocate($images_fin, 0, 0, 0);
ImageFill($images_fin, 0, 0, $background);

ImageCopyResampled($images_fin, $images_orig, $width / 2 - $scaleW / 2, $height / 2 - $scaleH / 2, 0, 0, $scaleW+1, $scaleH+1, $photoX, $photoY);

This will ensure that the resulting image always fits inside the 940x370 dimensions. The remainder of the image (if the aspect ratio didn't match 940 by 370) will be filled in with black.

Overv
  • 8,433
  • 2
  • 40
  • 70
  • :First of all thanks for your help. I tried your code. After executing it I got the image quality of uploaded image intact but this uploaded image is having width of 493px instead of 940px. The height is perfect i.e. 370 px. If this last issue gets resolve then it will be great man. – PHPLover Oct 05 '14 at 14:17
  • :Actually I want a generalized code. Have you written code by keeping only this image in mind? – PHPLover Oct 05 '14 at 14:22
  • @user2839497 These are all the possible ways your image can be resized to 940x370: http://imgur.com/a/cLJVg Which one do you want? – Overv Oct 05 '14 at 14:25
  • I want the second one. Since it's not missing any part of the image. But I want the resolution of 940 * 370 at the same time. – PHPLover Oct 05 '14 at 14:29
  • :What's $width and $height contain? One more query I have in this code is you haven't used 940 and 370 anywhere in your code. – PHPLover Oct 05 '14 at 14:38
  • @user2839497 $width and $height contain the same as your original code. They are the 940 and 370 values. – Overv Oct 05 '14 at 14:38
  • :Yes man, it's working well. Filling the remaining space with black background. The only doubt I still have in my mind is will the black colored background affect the feel of a image slider when this image will be displayed in the slider? – PHPLover Oct 05 '14 at 14:52