З вашого запитання, здається, ви щось нове для GD, я поділюсь деяким своїм досвідом, можливо, це трохи не в темі, але я думаю, що це буде корисно для когось нового в GD, як ви:
Крок 1, перевірити файл. Використовуйте наступну функцію, щоб перевірити, чи є $_FILES['image']['tmp_name']
файл дійсним:
function getContentsFromImage($image) {
if (@is_file($image) == true) {
return file_get_contents($image);
} else {
throw new \Exception('Invalid image');
}
}
$contents = getContentsFromImage($_FILES['image']['tmp_name']);
Крок 2, отримання формату файлу Спробуйте наступну функцію з розширенням finfo, щоб перевірити формат файлу файлу (вміст). Ви сказали б, чому б вам просто $_FILES["image"]["type"]
не перевірити формат файлу? Тому що це тільки перевірити розширення файлу не вміст файлу, якщо хто - то перейменуйте файл спочатку названий world.png до world.jpg , $_FILES["image"]["type"]
поверне JPEG НЕ PNG, так що $_FILES["image"]["type"]
може повернути невірний результат.
function getFormatFromContents($contents) {
$finfo = new \finfo();
$mimetype = $finfo->buffer($contents, FILEINFO_MIME_TYPE);
switch ($mimetype) {
case 'image/jpeg':
return 'jpeg';
break;
case 'image/png':
return 'png';
break;
case 'image/gif':
return 'gif';
break;
default:
throw new \Exception('Unknown or unsupported image format');
}
}
$format = getFormatFromContents($contents);
Крок 3, Отримати ресурс GD Отримати ресурс GD із вмісту, який ми мали раніше:
function getGDResourceFromContents($contents) {
$resource = @imagecreatefromstring($contents);
if ($resource == false) {
throw new \Exception('Cannot process image');
}
return $resource;
}
$resource = getGDResourceFromContents($contents);
Крок 4, отримайте розмір зображення Тепер ви можете отримати розмір зображення за допомогою наступного простого коду:
$width = imagesx($resource);
$height = imagesy($resource);
Тепер давайте подивимося, яку змінну ми отримали від вихідного зображення:
$contents, $format, $resource, $width, $height
OK, lets move on
Крок 5, обчислення аргументів розміру зображення Цей крок пов’язаний з вашим запитанням, метою наступної функції є отримання аргументів зміни розміру для функції GD imagecopyresampled()
, код якийсь довгий, але чудово працює, у нього навіть є три варіанти: розтягнути, зменшити , і заповніть.
stretch : розмір вихідного зображення такий самий, як і новий розмір, який ви встановили. Не буде дотримуватися співвідношення висота / ширина.
зменшити : розмір вихідного зображення не перевищуватиме новий розмір, який ви надаєте, і зберегти співвідношення висоти / ширини зображення.
заливка : розмір вихідного зображення буде таким самим, як новий розмір, який ви надаєте, він буде обрізати та змінити розмір зображення, якщо потрібно, і збереже співвідношення висоти / ширини зображення. Цей варіант - це те, що вам потрібно у вашому запитанні.
function getResizeArgs($width, $height, $newwidth, $newheight, $option) {
if ($option === 'stretch') {
if ($width === $newwidth && $height === $newheight) {
return false;
}
$dst_w = $newwidth;
$dst_h = $newheight;
$src_w = $width;
$src_h = $height;
$src_x = 0;
$src_y = 0;
} else if ($option === 'shrink') {
if ($width <= $newwidth && $height <= $newheight) {
return false;
} else if ($width / $height >= $newwidth / $newheight) {
$dst_w = $newwidth;
$dst_h = (int) round(($newwidth * $height) / $width);
} else {
$dst_w = (int) round(($newheight * $width) / $height);
$dst_h = $newheight;
}
$src_x = 0;
$src_y = 0;
$src_w = $width;
$src_h = $height;
} else if ($option === 'fill') {
if ($width === $newwidth && $height === $newheight) {
return false;
}
if ($width / $height >= $newwidth / $newheight) {
$src_w = (int) round(($newwidth * $height) / $newheight);
$src_h = $height;
$src_x = (int) round(($width - $src_w) / 2);
$src_y = 0;
} else {
$src_w = $width;
$src_h = (int) round(($width * $newheight) / $newwidth);
$src_x = 0;
$src_y = (int) round(($height - $src_h) / 2);
}
$dst_w = $newwidth;
$dst_h = $newheight;
}
if ($src_w < 1 || $src_h < 1) {
throw new \Exception('Image width or height is too small');
}
return array(
'dst_x' => 0,
'dst_y' => 0,
'src_x' => $src_x,
'src_y' => $src_y,
'dst_w' => $dst_w,
'dst_h' => $dst_h,
'src_w' => $src_w,
'src_h' => $src_h
);
}
$args = getResizeArgs($width, $height, 150, 170, 'fill');
Крок 6, зміна розміру зображення Використовуйте $args
, $width
, $height
, $format
і $ ресурс , який ми отримали з вище в наступних опцій і отримати новий ресурс відредаговану фотографію:
function runResize($width, $height, $format, $resource, $args) {
if ($args === false) {
return;
}
$newimage = imagecreatetruecolor($args['dst_w'], $args['dst_h']);
if ($format === 'png') {
imagealphablending($newimage, false);
imagesavealpha($newimage, true);
$transparentindex = imagecolorallocatealpha($newimage, 255, 255, 255, 127);
imagefill($newimage, 0, 0, $transparentindex);
} else if ($format === 'gif') {
$transparentindex = imagecolorallocatealpha($newimage, 255, 255, 255, 127);
imagefill($newimage, 0, 0, $transparentindex);
imagecolortransparent($newimage, $transparentindex);
}
imagecopyresampled($newimage, $resource, $args['dst_x'], $args['dst_y'], $args['src_x'], $args['src_y'], $args['dst_w'], $args['dst_h'], $args['src_w'], $args['src_h']);
imagedestroy($resource);
return $newimage;
}
$newresource = runResize($width, $height, $format, $resource, $args);
Крок 7, отримуйте новий вміст , використовуйте таку функцію для отримання вмісту з нового ресурсу GD:
function getContentsFromGDResource($resource, $format) {
ob_start();
switch ($format) {
case 'gif':
imagegif($resource);
break;
case 'jpeg':
imagejpeg($resource, NULL, 100);
break;
case 'png':
imagepng($resource, NULL, 9);
}
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
$newcontents = getContentsFromGDResource($newresource, $format);
Крок 8, отримайте розширення , використовуйте наступну функцію, щоб отримати розширення з формату зображення (примітка, формат зображення не дорівнює розширенню зображення):
function getExtensionFromFormat($format) {
switch ($format) {
case 'gif':
return 'gif';
break;
case 'jpeg':
return 'jpg';
break;
case 'png':
return 'png';
}
}
$extension = getExtensionFromFormat($format);
Крок 9 збереження зображення Якщо у нас є користувач з ім'ям mike, ви можете зробити наступне, воно збережеться в тій же папці, що і цей php-скрипт:
$user_name = 'mike';
$filename = $user_name . '.' . $extension;
file_put_contents($filename, $newcontents);
Крок 10 знищити ресурс Не забудьте знищити ресурс GD!
imagedestroy($newresource);
або ви можете записати весь свій код у клас, і просто скористайтеся наступним:
public function __destruct() {
@imagedestroy($this->resource);
}
ПОРАДИ
Я рекомендую не перетворювати формат файлу, який завантажує користувач, ви зіткнетеся з багатьма проблемами.