Изменение размера изображения в PHP
Я хочу написать некоторый PHP-код, который автоматически изменяет размер любого изображения, загружаемого через форму на 147x147px, но я не знаю, как это сделать (я относительный начинающий PHP).
До сих пор у меня успешно загружались изображения, распознавались типы файлов и имена, но я хотел бы добавить функциональность изменения размера в код. Например, у меня есть тестовое изображение размером 2,3 МБ и 1331х1331 в размерности, и я бы хотел, чтобы его размер уменьшался, что, как я полагаю, значительно сжимает размер файла изображения.
До сих пор у меня есть следующее:
if ($_FILES) {
//Put file properties into variables
$file_name = $_FILES['profile-image']['name'];
$file_size = $_FILES['profile-image']['size'];
$file_tmp_name = $_FILES['profile-image']['tmp_name'];
//Determine filetype
switch ($_FILES['profile-image']['type']) {
case 'image/jpeg': $ext = "jpg"; break;
case 'image/png': $ext = "png"; break;
default: $ext = ''; break;
}
if ($ext) {
//Check filesize
if ($file_size < 500000) {
//Process file - clean up filename and move to safe location
$n = "$file_name";
$n = ereg_replace("[^A-Za-z0-9.]", "", $n);
$n = strtolower($n);
$n = "avatars/$n";
move_uploaded_file($file_tmp_name, $n);
} else {
$bad_message = "Please ensure your chosen file is less than 5MB.";
}
} else {
$bad_message = "Please ensure your image is of filetype .jpg or.png.";
}
}
$query = "INSERT INTO users (image) VALUES ('$n')";
mysql_query($query) or die("Insert failed. " . mysql_error() . "<br />" . $query);
Ответы
Ответ 1
Для работы с изображениями вам нужно использовать либо PHP ImageMagick, либо GD.
С GD, например, это так же просто, как...
function resize_image($file, $w, $h, $crop=FALSE) {
list($width, $height) = getimagesize($file);
$r = $width / $height;
if ($crop) {
if ($width > $height) {
$width = ceil($width-($width*abs($r-$w/$h)));
} else {
$height = ceil($height-($height*abs($r-$w/$h)));
}
$newwidth = $w;
$newheight = $h;
} else {
if ($w/$h > $r) {
$newwidth = $h*$r;
$newheight = $h;
} else {
$newheight = $w/$r;
$newwidth = $w;
}
}
$src = imagecreatefromjpeg($file);
$dst = imagecreatetruecolor($newwidth, $newheight);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
return $dst;
}
И вы можете вызвать эту функцию, например...
$img = resize_image(‘/path/to/some/image.jpg’, 200, 200);
Из личного опыта повторная дискретизация изображения GD также значительно уменьшает размер файла, особенно при повторной дискретизации исходных изображений цифровой камеры.
Ответ 2
Существует одна очень простая функция повторного масштабирования изображений для всех типов изображений, которые сохраняют прозрачность и очень просты в использовании.
проверить:
http://www.nimrodstech.com/php-image-resize/
https://github.com/Nimrod007/PHP_image_resize
надеюсь, что это поможет
Ответ 3
Этот ресурс также заслуживает внимания - некоторый очень аккуратный код, который использует GD. Тем не менее, я изменил их окончательный фрагмент кода для создания этой функции, которая соответствует требованиям OP...
function store_uploaded_image($html_element_name, $new_img_width, $new_img_height) {
$target_dir = "your-uploaded-images-folder/";
$target_file = $target_dir . basename($_FILES[$html_element_name]["name"]);
$image = new SimpleImage();
$image->load($_FILES[$html_element_name]['tmp_name']);
$image->resize($new_img_width, $new_img_height);
$image->save($target_file);
return $target_file; //return name of saved file in case you want to store it in you database or show confirmation message to user
}
Вам также потребуется включить этот файл PHP...
<?php
/*
* File: SimpleImage.php
* Author: Simon Jarvis
* Copyright: 2006 Simon Jarvis
* Date: 08/11/06
* Link: http://www.white-hat-web-design.co.uk/blog/resizing-images-with-php/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
* http://www.gnu.org/licenses/gpl.html
*
*/
class SimpleImage {
var $image;
var $image_type;
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$this->image = imagecreatefromjpeg($filename);
} elseif( $this->image_type == IMAGETYPE_GIF ) {
$this->image = imagecreatefromgif($filename);
} elseif( $this->image_type == IMAGETYPE_PNG ) {
$this->image = imagecreatefrompng($filename);
}
}
function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image,$filename,$compression);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image,$filename);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image,$filename);
}
if( $permissions != null) {
chmod($filename,$permissions);
}
}
function output($image_type=IMAGETYPE_JPEG) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image);
}
}
function getWidth() {
return imagesx($this->image);
}
function getHeight() {
return imagesy($this->image);
}
function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$height);
}
function resize($width,$height) {
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
}
?>
Ответ 4
Если вы не заботитесь об аспекте рациона (т.е. хотите, чтобы изображение было привязано к определенному размеру), вот упрощенный ответ
// for jpg
function resize_imagejpg($file, $w, $h) {
list($width, $height) = getimagesize($file);
$src = imagecreatefromjpeg($file);
$dst = imagecreatetruecolor($w, $h);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $w, $h, $width, $height);
return $dst;
}
// for png
function resize_imagepng($file, $w, $h) {
list($width, $height) = getimagesize($file);
$src = imagecreatefrompng($file);
$dst = imagecreatetruecolor($w, $h);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $w, $h, $width, $height);
return $dst;
}
// for gif
function resize_imagegif($file, $w, $h) {
list($width, $height) = getimagesize($file);
$src = imagecreatefromgif($file);
$dst = imagecreatetruecolor($w, $h);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $w, $h, $width, $height);
return $dst;
}
Теперь давайте обработаем загружаемую часть.
На первом этапе загрузите файл в нужный каталог. Затем вызывается одна из вышеперечисленных функций на основе типа файла (jpg, png или gif) и передает абсолютный путь вашего загруженного файла, как показано ниже:
// jpg change the dimension 750, 450 to your desired values
$img = resize_imagejpg('path/image.jpg', 750, 450);
Возвращаемое значение $img
- объект ресурса. Мы можем сохранить новое местоположение или переопределить оригинал, как показано ниже:
// again for jpg
imagejpeg($img, 'path/newimage.jpg');
Надеюсь, это поможет кому-то. Проверьте эти ссылки для более подробного изменения размера Imagick:: resizeImage и
imagejpeg()
Ответ 5
Я надеюсь, что это сработает для вас.
/**
* Image re-size
* @param int $width
* @param int $height
*/
function ImageResize($width, $height, $img_name)
{
/* Get original file size */
list($w, $h) = getimagesize($_FILES['logo_image']['tmp_name']);
/*$ratio = $w / $h;
$size = $width;
$width = $height = min($size, max($w, $h));
if ($ratio < 1) {
$width = $height * $ratio;
} else {
$height = $width / $ratio;
}*/
/* Calculate new image size */
$ratio = max($width/$w, $height/$h);
$h = ceil($height / $ratio);
$x = ($w - $width / $ratio) / 2;
$w = ceil($width / $ratio);
/* set new file name */
$path = $img_name;
/* Save image */
if($_FILES['logo_image']['type']=='image/jpeg')
{
/* Get binary data from image */
$imgString = file_get_contents($_FILES['logo_image']['tmp_name']);
/* create image from string */
$image = imagecreatefromstring($imgString);
$tmp = imagecreatetruecolor($width, $height);
imagecopyresampled($tmp, $image, 0, 0, $x, 0, $width, $height, $w, $h);
imagejpeg($tmp, $path, 100);
}
else if($_FILES['logo_image']['type']=='image/png')
{
$image = imagecreatefrompng($_FILES['logo_image']['tmp_name']);
$tmp = imagecreatetruecolor($width,$height);
imagealphablending($tmp, false);
imagesavealpha($tmp, true);
imagecopyresampled($tmp, $image,0,0,$x,0,$width,$height,$w, $h);
imagepng($tmp, $path, 0);
}
else if($_FILES['logo_image']['type']=='image/gif')
{
$image = imagecreatefromgif($_FILES['logo_image']['tmp_name']);
$tmp = imagecreatetruecolor($width,$height);
$transparent = imagecolorallocatealpha($tmp, 0, 0, 0, 127);
imagefill($tmp, 0, 0, $transparent);
imagealphablending($tmp, true);
imagecopyresampled($tmp, $image,0,0,0,0,$width,$height,$w, $h);
imagegif($tmp, $path);
}
else
{
return false;
}
return true;
imagedestroy($image);
imagedestroy($tmp);
}
Ответ 6
Просто используйте функцию PHP: дано как
// Read the image
$img = imagecreatefromjpeg("source_of_img.jpg");
// Now resize the image width = 200 and height = 200
$imgresize = imagescale($img, 200, 200);
Ответ 7
(ВАЖНО: в случае изменения размера анимации (анимированные webp или gif), результатом будет не анимированное, но измененное изображение из первого кадра! (оригинальная анимация остается неизменной...)
Я создал это для своего проекта php 7.2 (пример imagebmp уверен (PHP 7> = 7.2.0):php/manual/function.imagebmp) о techfry.com/Учебник php, с GD2 (так что ничего сторонней библиотеки) и очень похож на ответ нико Бистолфи, но работает со всеми пятью базовыми изображениями mimetype (png, jpeg, webp, bmp и gif), создание нового файла с измененным размером, без изменения исходного файла и всего содержимого одной функции и готового к использованию (копирование и вставка в ваш проект). (Вы можете установить расширение нового файла с помощью пятого параметра или просто оставить его, если хотите сохранить оригинал):
function createResizedImage(
string $imagePath = '',
string $newPath = '',
int $newWidth = 0,
int $newHeight = 0,
string $outExt = 'DEFAULT'
) : ?string
{
if (
$newPath === '' or
file_exists($imagePath) === false
) {
return null;
}
if (
in_array(
(
$type = exif_imagetype($imagePath)
),
[IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_BMP, IMAGETYPE_WEBP]
) === false
) {
return null;
}
list($width, $height) = getimagesize($imagePath);
$outBool = in_array($outExt, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']);
switch (true)
{
case $type === IMAGETYPE_JPEG:
$image = imagecreatefromjpeg($imagePath);
if ($outBool === false) $outExt = 'jpg';
break;
case $type === IMAGETYPE_PNG:
$image = imagecreatefrompng($imagePath);
if ($outBool === false) $outExt = 'png';
break;
case $type === IMAGETYPE_GIF:
$image = imagecreatefromgif($imagePath);
if ($outBool === false) $outExt = 'gif';
break;
case $type === IMAGETYPE_BMP:
$image = imagecreatefrombmp($imagePath);
if ($outBool === false) $outExt = 'bmp';
break;
case $type === IMAGETYPE_WEBP:
$image = imagecreatefromwebp($imagePath);
if ($outBool === false) $outExt = 'webp';
}
$newImage = imagecreatetruecolor($newWidth, $newHeight);
//TRANSPARENT BACKGROUND
$color = imagecolorallocatealpha($newImage, 0, 0, 0, 127); //fill transparent back
imagefill($newImage, 0, 0, $color);
imagesavealpha($newImage, true);
//ROUTINE
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
// Rotate image on iOS
if(function_exists('exif_read_data') && $exif = exif_read_data($imagePath, 'IFD0'))
{
if(isset($exif['Orientation']) && isset($exif['Make']) && !empty($exif['Orientation']) && preg_match('/(apple|ios|iphone)/i', $exif['Make'])) {
switch($exif['Orientation']) {
case 8:
if ($width > $height) $newImage = imagerotate($newImage,90,0);
break;
case 3:
$newImage = imagerotate($newImage,180,0);
break;
case 6:
$newImage = imagerotate($newImage,-90,0);
break;
}
}
}
switch (true)
{
case in_array($outExt, ['jpg', 'jpeg']) === true: $success = imagejpeg($newImage, $newPath);
break;
case $outExt === 'png': $success = imagepng($newImage, $newPath);
break;
case $outExt === 'gif': $success = imagegif($newImage, $newPath);
break;
case $outExt === 'bmp': $success = imagebmp($newImage, $newPath);
break;
case $outExt === 'webp': $success = imagewebp($newImage, $newPath);
}
if ($success === false)
{
return null;
}
return $newPath;
}
Ответ 8
Я создал простую в использовании библиотеку для изменения размера изображения. Это можно найти здесь, на Github.
Пример использования библиотеки:
// Include PHP Image Magician library
require_once('php_image_magician.php');
// Open JPG image
$magicianObj = new imageLib('racecar.jpg');
// Resize to best fit then crop (check out the other options)
$magicianObj -> resizeImage(100, 200, 'crop');
// Save resized image as a PNG (or jpg, bmp, etc)
$magicianObj -> saveImage('racecar_small.png');
Другие функции, если они вам нужны:
- Быстрое и простое изменение размера - изменение размера на альбомную, портретную или авто
- Легкий урожай
- Добавить текст
- Регулировка качества
- Водяные знаки
- Тени и отражения
- Поддержка прозрачности
- Прочитать EXIF метаданные
- Границы, Закругленные углы, Вращение
- Фильтры и эффекты
- Резкость изображения
- Преобразование типа изображения
- Поддержка BMP
Ответ 9
ZF cake:
<?php
class FkuController extends Zend_Controller_Action {
var $image;
var $image_type;
public function store_uploaded_image($html_element_name, $new_img_width, $new_img_height) {
$target_dir = APPLICATION_PATH . "/../public/1/";
$target_file = $target_dir . basename($_FILES[$html_element_name]["name"]);
//$image = new SimpleImage();
$this->load($_FILES[$html_element_name]['tmp_name']);
$this->resize($new_img_width, $new_img_height);
$this->save($target_file);
return $target_file;
//return name of saved file in case you want to store it in you database or show confirmation message to user
public function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$this->image = imagecreatefromjpeg($filename);
} elseif( $this->image_type == IMAGETYPE_GIF ) {
$this->image = imagecreatefromgif($filename);
} elseif( $this->image_type == IMAGETYPE_PNG ) {
$this->image = imagecreatefrompng($filename);
}
}
public function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image,$filename,$compression);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image,$filename);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image,$filename);
}
if( $permissions != null) {
chmod($filename,$permissions);
}
}
public function output($image_type=IMAGETYPE_JPEG) {
if( $image_type == IMAGETYPE_JPEG ) {
imagejpeg($this->image);
} elseif( $image_type == IMAGETYPE_GIF ) {
imagegif($this->image);
} elseif( $image_type == IMAGETYPE_PNG ) {
imagepng($this->image);
}
}
public function getWidth() {
return imagesx($this->image);
}
public function getHeight() {
return imagesy($this->image);
}
public function resizeToHeight($height) {
$ratio = $height / $this->getHeight();
$width = $this->getWidth() * $ratio;
$this->resize($width,$height);
}
public function resizeToWidth($width) {
$ratio = $width / $this->getWidth();
$height = $this->getheight() * $ratio;
$this->resize($width,$height);
}
public function scale($scale) {
$width = $this->getWidth() * $scale/100;
$height = $this->getheight() * $scale/100;
$this->resize($width,$height);
}
public function resize($width,$height) {
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
public function savepicAction() {
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$this->_response->setHeader('Access-Control-Allow-Origin', '*');
$this->db = Application_Model_Db::db_load();
$ouser = $_POST['ousername'];
$fdata = 'empty';
if (isset($_FILES['picture']) && $_FILES['picture']['size'] > 0) {
$file_size = $_FILES['picture']['size'];
$tmpName = $_FILES['picture']['tmp_name'];
//Determine filetype
switch ($_FILES['picture']['type']) {
case 'image/jpeg': $ext = "jpg"; break;
case 'image/png': $ext = "png"; break;
case 'image/jpg': $ext = "jpg"; break;
case 'image/bmp': $ext = "bmp"; break;
case 'image/gif': $ext = "gif"; break;
default: $ext = ''; break;
}
if($ext) {
//if($file_size<400000) {
$img = $this->store_uploaded_image('picture', 90,82);
//$fp = fopen($tmpName, 'r');
$fp = fopen($img, 'r');
$fdata = fread($fp, filesize($tmpName));
$fdata = base64_encode($fdata);
fclose($fp);
//}
}
}
if($fdata=='empty'){
}
else {
$this->db->update('users',
array(
'picture' => $fdata,
),
array('username=?' => $ouser ));
}
}
Ответ 10
Вы можете попробовать использовать библиотеку TinyPNG PHP. Используя эту библиотеку, ваш образ автоматически оптимизируется во время процесса изменения размера. Все, что вам нужно, чтобы установить библиотеку и получить ключ API из https://tinypng.com/developers. Чтобы установить библиотеку, выполните приведенную ниже команду.
composer require tinify/tinify
После этого ваш код выглядит следующим образом.
require_once("vendor/autoload.php");
\Tinify\setKey("YOUR_API_KEY");
$source = \Tinify\fromFile("large.jpg"); //image to be resize
$resized = $source->resize(array(
"method" => "fit",
"width" => 150,
"height" => 100
));
$resized->toFile("thumbnail.jpg"); //resized image
У меня есть блог, написанный по той же теме http://artisansweb.net/resize-image-php-using-tinypng
Ответ 11
Я бы порекомендовал вам использовать piio.co. После того, как вы загрузили изображения в свое хранилище, вы просто используете исходный URL-адрес изображения в <img/>
и библиотека автоматически выполнит изменение размера за вас.
Ваш тег изображения будет выглядеть так:
<img data-piio="/image/gallery/p/image1.jpg"/>
Затем, как только вы инициализируете скрипт Piio, он автоматически изменит размер изображения и отправит его из CDN.
Здесь ссылка на документы
Если вы хотите сделать это вручную, то я рекомендую использовать встроенные функции php, для этого будет использоваться библиотека GD. Например, если вы хотите изменить размер JPEG, вы можете начать с:
list($width, $height) = getimagesize($filepath);
$original = imagecreatefromjpeg($filepath);
$thumb = imagecreatetruecolor($new_width, $new_height);
imagecopyresized($thumb, $original, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
Для непосредственного вывода изображения:
imagejpeg($thumb);
Чтобы сохранить изображение в файл:
imagejpeg($thumb, 'filepath/image.jpg');
Ответ 12
Я нашел математический способ сделать эту работу
Репозиторий Github - https://github.com/gayanSandamal/easy-php-image-resizer
Живой пример - https://plugins.nayague.com/easy-php-image-resizer/
<?php
//path for the image
$source_url = '2018-04-01-1522613288.PNG';
//separate the file name and the extention
$source_url_parts = pathinfo($source_url);
$filename = $source_url_parts['filename'];
$extension = $source_url_parts['extension'];
//define the quality from 1 to 100
$quality = 10;
//detect the width and the height of original image
list($width, $height) = getimagesize($source_url);
$width;
$height;
//define any width that you want as the output. mine is 200px.
$after_width = 200;
//resize only when the original image is larger than expected with.
//this helps you to avoid from unwanted resizing.
if ($width > $after_width) {
//get the reduced width
$reduced_width = ($width - $after_width);
//now convert the reduced width to a percentage and round it to 2 decimal places
$reduced_radio = round(($reduced_width / $width) * 100, 2);
//ALL GOOD! let reduce the same percentage from the height and round it to 2 decimal places
$reduced_height = round(($height / 100) * $reduced_radio, 2);
//reduce the calculated height from the original height
$after_height = $height - $reduced_height;
//Now detect the file extension
//if the file extension is 'jpg', 'jpeg', 'JPG' or 'JPEG'
if ($extension == 'jpg' || $extension == 'jpeg' || $extension == 'JPG' || $extension == 'JPEG') {
//then return the image as a jpeg image for the next step
$img = imagecreatefromjpeg($source_url);
} elseif ($extension == 'png' || $extension == 'PNG') {
//then return the image as a png image for the next step
$img = imagecreatefrompng($source_url);
} else {
//show an error message if the file extension is not available
echo 'image extension is not supporting';
}
//HERE YOU GO :)
//Let do the resize thing
//imagescale([returned image], [width of the resized image], [height of the resized image], [quality of the resized image]);
$imgResized = imagescale($img, $after_width, $after_height, $quality);
//now save the resized image with a suffix called "-resized" and with its extension.
imagejpeg($imgResized, $filename . '-resized.'.$extension);
//Finally frees any memory associated with image
//**NOTE THAT THIS WONT DELETE THE IMAGE
imagedestroy($img);
imagedestroy($imgResized);
}
?>