Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make the code written for image-resizing workable and optimized for all kinds of image extensions?

Basically, I'm using PHP and HTML for my website. I'm a newbie to PHP. So I request you to please correct me if I've made any mistake in my code or approach.

I've written code for re-sizing the image uploaded by user to specific size(i.e. specific width and height). I want to make the uploaded image of dimension 940 px * 370 px. But while doing so I want to take care of following issues :

  1. The overall quality of image saved to the server after modification of it's dimensions should be equal as of the image uploaded by user. It shouldn't get shrink or stretch, it's original colors shouldn't get disturbed, etc. All the content of image should be as it is but within the dimensions of 940 px * 370 px.
  2. Black colored background should not be added to the image saved on server.
  3. The code should be workable for all standard image formats. That is if the image uploaded by user is in any of the standard image formats it should get re-sized otherwise not.

So for achieving above functionalities I've written following code :

HTML Code(upload_file.html):

<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(upload_file.php):

<?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/upload" . $_FILES["file"]["name"])) {
          echo $_FILES["file"]["name"] . " already exists. ";
        } else {
          //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);

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

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

          /*$width = $scale * $photoX;
          $height = $scale * $photoY;*/

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

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

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

          /*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);*/
          ImageCopyResampled($images_fin, $images_orig, $width / 2 - $scaleW / 2, $height / 2 - $scaleH / 2, 0, 0, $scaleW+1, $scaleH+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";
    }
?>

Note : To test the above code and see the uploaded image please create a folder with titled "upload" proper permissions in the same directory where the files upload_file.html and upload_file.php are present.

Actually, the above code is working for me but it has few issues as follows:

  1. It's giving warnings for image files with extensions other than .jpg. It should not happen.
  2. The image is saving to the server after modifications in it's dimensions (940 px * 370px). The quality of image saved to the server is same as of original image uploaded by user but it's adding additional black space in the background to the image. It should not happen.

You can check the code functionality on your local machine by uploading images whose dimensions are higher than 940 px * 370 px and size not greater than 5 MB.

It would be immensely helpful for me if someone could help me in resolving above two issues.

like image 816
PHPFan Avatar asked Oct 11 '14 06:10

PHPFan


People also ask

How do I make an image fit my screen size in HTML?

One of the simplest ways to resize an image in the HTML is using the height and width attributes on the img tag. These values specify the height and width of the image element. The values are set in px i.e. CSS pixels.

Which tool is used for resizing an image?

BeFunky is a great free image resize tool that offers a lot of options. You can resize your image by width or height or by percentage scale.


1 Answers

Answer to your first question

It's giving warnings for image files with extensions other than .jpg. It should not happen.

You get warnings because you are opening your image whatever the format using the JPEG-specific function:

// line 48
$images_orig = ImageCreateFromJPEG($images);

To fix this issue, you you can use the generic imagecreatefromstring function, which opens images without taking care of their format.

// line 48
$images_orig = ImageCreateFromString(file_get_contents($images));

Resources:

  • imagecreatefromstring
  • file_get_contents

Answer to your second question

the image is saving to the server after modifications in it's dimensions (940 px * 370px). The quality of image saved to the server is same as of original image uploaded by user but it's adding additional black space in the background to the image. It should not happen.

There are 2 mistakes here:

  • You are resampling your image without specifying that the target gd image should support transparency
  • You are saving the result as JPEG, but JPEG does not support transparency.

You are resampling your image without specifying that the target gd image should support transparency.

To implement it, you should first choose the transparent color in the target image: I am used to use light pink (#FF00FF) as transparent as this is not a common color on images (if you're uploading flowers pics, choose another color :-)). Then, before copying the source image to the target image, set the background color to light pink: the whole image will become transparent instead of black.

Replace:

     // line 67
     $images_fin = ImageCreateTrueColor($width, $height);

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

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

By the following lines:

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

     $transparent = ImageColorAllocate($images_fin, 255, 0, 255);
     ImageFill($images_fin, 0, 0, $transparent);
     ImageColorTransparent($images_fin, $transparent);

You are saving the result as JPEG, but JPEG does not support transparency.

To fix this issue, just replace:

     // line 31
     $new_images = "upload" . $_FILES["file"]["name"];
     // line 85
     ImageJPEG($images_fin, "upload/" . $new_images);
     // line 93
     echo "Stored in: " . "upload/" . $_FILES["file"]["name"];

By:

     // line 31
     $new_images = "upload" . $_FILES["file"]["name"] . '.png';
     // line 85
     ImagePNG($images_fin, "upload/" . $new_images);
     // line 93
     echo "Stored in: " . "upload/" . $new_images;

Resources:

  • imagecolortransparent
  • imagepng

Your code, with the fixes above

<?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/upload" . $_FILES["file"]["name"]))
      {
         echo $_FILES["file"]["name"] . " already exists. ";
      }
      else
      {
         //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"] . '.png';


         //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 = ImageCreateFromString(file_get_contents($images));

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

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

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

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

         /* $width = $scale * $photoX;
           $height = $scale * $photoY; */

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

         /* 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); */
         ImageCopyResampled($images_fin, $images_orig, $width / 2 - $scaleW / 2, $height / 2 - $scaleH / 2, 0, 0,
            $scaleW + 1, $scaleH + 1, $photoX, $photoY);

         /* Output image to browser or file
          * creates a JPEG file from the given image.
          */
         ImagePNG($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/" . $new_images;
      }
   }
}
else
{
   echo "Invalid file";
}

enter image description here

like image 50
Alain Tiemblo Avatar answered Sep 27 '22 17:09

Alain Tiemblo