drjk87189
2014-10-05 13:42
浏览 39
已采纳

即使在使用PHP GD功能后,为什么在图像重新调整大小时上传图像质量的质量会受到严重影响?

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

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dtwxt88240 2014-10-05 14:10
    已采纳

    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.

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题