How to make code written for image resizing efficient and optimized for all kinds of image extensions?

Basically, I use PHP and HTML for my site. I am new to PHP. Therefore, I ask you to correct me if I am mistaken in my code or approach.

I wrote code to recalibrate the image uploaded by the user to a specific size (i.e., a specific width and height). I want to make a downloaded image 940 px * 370 px in size. But at the same time I want to take care of the following problems:

  • The overall quality of the image stored on the server after changing its size should be the same as the image uploaded by the user. It should not shrink or stretch, its original colors should not be broken, etc. All image content should be as it is, but within the size of 940 px * 370 px .
  • The black and white background should not be added to the image stored on the server.
  • The code must be workable for all standard image formats. That is, if the image uploaded by the user is in any of the standard image formats, it must be changed in another way.

So, to achieve the above functionality, I wrote the 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 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 check the code above and view the downloaded image, create a folder with the corresponding inscriptions "upload" in the same directory where the files upload_file.html and upload_file.php are present.

Actually, the above code works for me, but it has several problems:

  • It gives warnings for image files with extensions other than .jpg . It should not be.
  • The image is saved on the server after changing its size ( 940 px * 370px ). The quality of the image stored on the server is the same as the original image uploaded by the user, but it adds additional additional space in the background to the image. This should not happen.

You can test the functionality of the code on your local computer by downloading images that are larger than 940 px * 370 px and no larger than 5 MB in size.

It would be very helpful for me if someone would help me solve two problems.

+6
source share
2 answers

Answer your first question

It gives warnings for image files with extensions other than .jpg. It should not be.

You get warnings because you open your image regardless of format using a specific JPEG function:

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

To fix this problem, you can use the universal function imagecreatefromstring , which opens images without worrying about their format.

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

Resources


The answer to the second question

the image is saved on the server after making changes to its size (940 px * 370px). The quality of the image stored on the server is the same as the original image uploaded by the user, but it adds additional black space in the background to the image. This should not happen.

There are two errors here:

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

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

To implement it, you must first select a transparent color in the target image: I use light pink (# FF00FF) as transparent, since this is not an ordinary color in the images (if you upload photos of flowers, choose a different color :-)). Then, before copying the source image to the target image, set the background color to light pink: the entire image will become transparent, not black.

Replace:

  // line 67 $images_fin = ImageCreateTrueColor($width, $height); $background = ImageColorAllocate($images_fin, 0, 0, 0); ImageFill($images_fin, 0, 0, $background); 

In 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 save the result as JPEG, but JPEG does not support transparency .

To fix this problem, simply 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


Your code with corrections 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 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

+13
source

This is what you can work on:

  • To create an image resource, you always use the ImageCreateFromJPEG function, which only processes jpeg images, but you must use the correct function for different types, for example ImageCreateFromPNG.
  • You save the resulting image in JPEG format, but the jpeg format does not support transparency. ImagePNG is the right function.
  • You create a solid color for your background. It should be transparent. Edit: here is the relevant piece of code to make it truly transparent:

      $images_fin = ImageCreateTrueColor($width, $height); imagesavealpha($images_fin, true); $background = ImageColorAllocateAlpha($images_fin, 0x00,0x00,0x00, 127); imagefill($images_fin, 0, 0, $background); 

Here is the working version of your code. Keep in mind that you can add more cases to the switch statement, which takes care of the first problem.

 <?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 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. switch ($_FILES["file"]["type"]) { case '"image/gif"': $images_orig = imagecreatefromgif($images); break; case "image/png": $images_orig = ImageCreateFromPNG($images); break; case "image/jpg": $images_orig = ImageCreateFromJPEG($images); break; #TODO more cases for all the image types you want to support default: # code to handle other images type. break; } //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); //added these calls to handle transparency. imagesavealpha($images_fin, true); $background = ImageColorAllocateAlpha($images_fin, 0x00,0x00,0x00, 127); 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, $width / 2 - $scaleW / 2, $height / 2 - $scaleH / 2, 0, 0, $scaleW+1, $scaleH+1, $photoX, $photoY); /*Output image to browser or file *creates a PNG 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/" . $_FILES["file"]["name"]; } } } else { echo "Invalid file"; } ?> 
0
source

Source: https://habr.com/ru/post/976600/


All Articles