Как сделать код, написанный для изменения размера изображения, работоспособным и оптимизированным для всех видов расширений изображений?

В основном я использую PHP и HTML для своего сайта. Я новичок в PHP. Поэтому я прошу вас исправить меня, если я допустил ошибку в своем коде или подходе.

Я написал код для изменения размера изображения, загружаемого пользователем, до определенного размера (то есть определенной ширины и высоты). Я хочу сделать загруженное изображение размера 940 пикселей * 370 пикселей. Но при этом я хочу позаботиться о следующих вопросах:

  1. Общее качество изображения, сохраненного на сервере после изменения его размеров, должно быть таким же, как и у изображения, загруженного пользователем. Он не должен сжиматься или растягиваться, его оригинальные цвета не должны нарушаться и т. Д. Все содержимое изображения должно быть таким, как оно есть, но в пределах размеров 940 пикселей * 370 пикселей.
  2. Черный цвет не следует добавлять к изображению, сохраненному на сервере.
  3. Код должен быть работоспособным для всех стандартных форматов изображений. То есть, если изображение, загруженное пользователем, имеет любой из стандартных форматов изображения, оно должно быть изменено в размерах, иначе нет.

Поэтому для достижения вышеуказанных функций я написал следующий код:

HTML-код (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-код (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";
}
?>

Замечания : Чтобы проверить приведенный выше код и увидеть загруженное изображение, создайте папку с соответствующими разрешениями «upload» в том же каталоге, где находятся файлы upload_file.html и upload_file.php.

На самом деле, приведенный выше код работает для меня, но у него есть несколько проблем:

  1. Он дает предупреждения для файлов изображений с расширениями, отличными от .jpg. Этого не должно быть.
  2. Изображение сохраняется на сервере после изменения его размеров (940 пикселей * 370 пикселей). Качество изображения, сохраненного на сервере, такое же, как и у исходного изображения, загруженного пользователем, но оно добавляет дополнительное черное пространство на заднем плане к изображению. Этого не должно быть.

Вы можете проверить функциональность кода на локальном компьютере, загрузив изображения, размеры которых превышают 940 пикселей * 370 пикселей и размер не больше чем 5 МБ.

Было бы очень полезно для меня, если бы кто-то мог помочь мне в решении выше двух вопросов.

6

Решение

Он дает предупреждения для файлов изображений с расширениями, отличными от .jpg.
Этого не должно быть.

Вы получаете предупреждения, потому что вы открываете свое изображение в любом формате, используя функцию JPEG:

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

Чтобы решить эту проблему, вы можете использовать общий imagecreatefromstring функция, которая открывает изображения, не заботясь об их формате.

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

Ресурсы:


после сохранения изменений изображение сохраняется на сервере
размеры (940 пикселей * 370 пикселей). Качество изображения сохранено на сервере
то же самое, что и исходное изображение, загруженное пользователем, но оно добавляет
дополнительное черное пространство на заднем плане к изображению. Не должно
бывает.

Здесь есть 2 ошибки:

  • Вы передискретизируете свое изображение, не указав, что целевое изображение gd должно поддерживать прозрачность
  • Вы сохраняете результат в формате JPEG, но JPEG не поддерживает прозрачность.

Вы пересэмплируете свое изображение, не указывая, что целевое изображение gd должно поддерживать прозрачность.

Чтобы реализовать это, вы должны сначала выбрать прозрачный цвет на целевом изображении: я привык использовать светло-розовый (# FF00FF) как прозрачный, так как это не обычный цвет на изображениях (если вы загружаете фотографии цветов, выберите другой цвет :-)). Затем, перед копированием исходного изображения на целевое изображение, установите цвет фона на светло-розовый: все изображение станет прозрачным, а не черным.

Заменить:

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

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

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

По следующим строкам:

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

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

Вы сохраняете результат в формате JPEG, но JPEG не поддерживает прозрачность.

Чтобы исправить эту проблему, просто замените:

     // 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"];

От:

     // 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;

Ресурсы:


<?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";
}

введите описание изображения здесь

13

Другие решения

Вот те вещи, над которыми вы можете поработать:

  1. Для создания ресурса изображения вы всегда используете ImageCreateFromJPEG
    функция, которая обрабатывает только изображения JPEG, но вы должны использовать
    правильная функция для разных типов, например
    ImageCreateFromPNG.
  2. Вы сохраняете полученное изображение в формате JPEG, но формат JPEG не поддерживает прозрачность. ImagePNG — правильная функция для использования.
  3. Вы создаете сплошной цвет для своего фона. Он должен быть прозрачным. Изменить: вот соответствующая часть кода, чтобы сделать его действительно прозрачным:

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

Вот это рабочая версия вашего кода. Имейте в виду, что вы можете добавить больше случаев в оператор switch, который решает первую проблему.

<?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.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

По вопросам рекламы [email protected]