Благодарю вас за то что не сбрасываете меня со счетов и не удаляете из ридера. Потому что я пишу когда у меня есть интересные задачи и вот сегодня я немного попишу про библиотеку GD2 и работу с ней средствами PHP
Задачка сегодня звучит так: надо загрузить на сайт два изображения (произвольного размера, разумеется) каждое изображение уменьшить до определенного размера с учетом пропорций и положить на один холст (с соотношением размеров 2:1 к размеру картинки) так чтобы обе картинки были в центре. В общем я не большой мастер объяснять на пальцах поэтому нарисовал вот такой эскиз.

Сначала я попробовал рещить эту задачу при помощи встроенной в CI (поскольку именно на CI я пишу в силу незнания других фреймворков) библиотеки которая умеет работать и с GD2 и с ImageMagic и с NetPBM. К сожалению библиотека оказалась очень громоздкой (в плане конфигурации) и не очень гибкой в плане функционала, поэтому написал три больших конфига и попытавшись отладить полученное я получил головняк на пару часов с виндовыми путями на локальной машине. Библиотека никак не хотела принимать абсолютные пути типа C:/localhost/path/to/file.jpg и относительные типа implode(DIRECTORY_SEPARATOR, array(«path»,»to»,»file.jpg»)) , в общем я сделал то чему меня учили в школе — положил на нее, и написал все на чистом PHP
Я не буду описывать как работает CI единственно что надо знать это что я перебираю массив $_FILES и преобразовываю его в массив фалов где каждый файл это элемент массива. итак внимание на экран, коменты по коду.
// это преобразование массива $_FILES в нечто человеко-удобное
$files = $this->getFileData('files');
// юник для базы и размер уменьшенной (квадратной) картинки
$uniqid = uniqid(); //md5(now());
$size = 450;
// проверяю наличие, тип файла и размер
$status = array();
$types = array("first","second");
foreach($types as $type){
if (!$files[$type]['tmp_name']){
$status[$type] = "а как же картинкa?";
} elseif (!in_array($files[$type]['type'], array('image/gif','image/jpeg','image/png'))){
$status[$type] = "это разве картинка?";
} elseif ($files[$type]['size'] > 1048576){
$status[$type] = "размер картинки больше 1M";
}
}
// если ошибки - выходим
if ($status){
echo json_encode($status);
exit;
}
// создаю холст на котором будет все это потом лежать и делаю его прозрачным
$sample = imagecreatetruecolor(2*$size, $size);
imagesavealpha($sample, true);
$transparent = imagecolorallocatealpha($sample, 0, 0, 0, 127);
imagefill($sample, 0, 0, $transparent);
// для каждой картинки
foreach($types as $type){
// переименовываю и переношу во временную папку
$files[$type]['new_name'] = TEMP_DIR.'/'.$type.$uniqid.".".end(explode('/', $files[$type]['type']));
move_uploaded_file($files[$type]['tmp_name'], $files[$type]['new_name']);
// узнаю реальные размеры и высчитываю какими они должны быть
$image[$type] = array();
list($image[$type]['width'], $image[$type]['height']) = getimagesize($files[$type]['new_name']);
$dim = $image[$type]['width'] > $image[$type]['height'] ? 'width' : 'height';
if($image[$type][$dim] < $size){
$image[$type]['new_width'] = $image[$type]['width'];
$image[$type]['new_height'] = $image[$type]['height'];
} else {
$image[$type]['ratio'] = $size / $image[$type][$dim] * 100;
$image[$type]['new_width'] = $image[$type]['width'] * $image[$type]['ratio'] / 100;
$image[$type]['new_height'] = $image[$type]['height'] * $image[$type]['ratio'] / 100;
}
// получаю саму картинку
switch ($files[$type]['type']){
case 'image/gif':
$image[$type]['source'] = imagecreatefromgif($files[$type]['new_name']);
break;
case 'image/jpeg':
$image[$type]['source'] = imagecreatefromjpeg($files[$type]['new_name']);
break;
case 'image/png':
$image[$type]['source'] = imagecreatefrompng($files[$type]['new_name']);
break;
}
// а теперь собственно магия - я рисую картинку на холсте
imagecopyresampled(
$sample,
$image[$type]['source'],
$type=='first'?$size-$image[$type]['new_width']:$size,
($size-$image[$type]['new_height'])/2,
0,
0,
$image[$type]['new_width'],
$image[$type]['new_height'],
$image[$type]['width'],
$image[$type]['height']
);
// удаляю ненужное
unlink($files[$type]['new_name']);
}
// и на последок сохраняю холст
imagepng($sample, implode(DIRECTORY_SEPARATOR, array('path','to',$uniqid.'.png')), 0);
imagedestroy($sample);
Конечно реальный код выглядит не так, там реальные пути и названия, что-то вынесено в отдельные методы, где-то юник сохраняется в базу, но общий смысл он сохранил. Приятного пользования.