Я пытался извлечь файл из HTML-формы, затем создать новую и использовать «imagecopyresampled», чтобы получить из нее центральный квадрат, помещаясь либо по X, либо по Y, в зависимости от того, что меньше.
К сожалению, я немного запутался в обработке такого количества изображений и временных имен, и у меня возникли проблемы с копированием файла в файл пользователя в системе.
Код выглядит следующим образом:
if($_FILES){
$valid = validate_image("avatar");
if ($valid){
list($width, $height, $type) = getimagesize($_FILES['avatar']['tmp_name']);
$scale = $width/$height;
$pixels = 150;
$tmp_name = $_FILES['avatar']['tmp_name'];
switch ($type) {
case IMAGETYPE_GIF:
$source = imagecreatefromgif($tmp_name);
break;
case IMAGETYPE_JPEG:
case IMAGETYPE_JPG:
$source = imagecreatefromjpeg($tmp_name);
break;
case IMAGETYPE_PNG:
$source = imagecreatefrompng($tmp_name);
break;
}
$upload = imagecreatetruecolor($pixels, $pixels);
//sketchy image math: Get whichever coordinate is smaller and that will be 150 on the thumbnail from top to bottom (or left to right).
//Then for the other one you know the size will be 150, but only for the part starting at (Coordinate/2)-SMALLERCOORD/2 to (coord/2)+SMALLERCOORD/2
if ($width>$height){
imagecopyresampled ($upload, $source, 0, 0, 0, ($width-$height/2), 150, 150, $height, $height);
} else if ($width<=$height){
imagecopyresampled ($upload, $source, 0, 0, 0, ($height-$width/2), 150, 150, $width, $width);
}
$name = "./users/$id/avatar.png";
imagepng($upload, $tmp_name);
if (!(move_uploaded_file($tmp_name, $name))) $fail .= "<h3>ERROR UPLOADING AVATAR. TRY AGAIN LATER OR CONTACT US.</h3><br>";
}
}
Прежде всего, позвольте мне понять, правильно ли я понимаю, как работает код:
Я получаю файл, проверяю, действителен ли он с моей функцией. Тогда я получу размер и тип этого. Я проверяю тип и создаю на нем изображение в памяти серверов и еще одно пустое изображение того размера, который мне нужен. Затем я на самом деле копирую уменьшенное и обрезанное изображение на созданное мной загружаемое изображение.
Там, если бы я хотел, я мог бы удалить временное «исходное» изображение с помощью imagedestroy, верно?
Далее я пытаюсь сделать png-файл из «загрузки» изображения из памяти сервера.
Вот где я думаю, что я ошибся, я не могу перезаписать временный файл, могу я?
И затем я пытаюсь поместить изображение временное изображение, где оно должно быть загружено, но это не работает.
Я правильно понял? Как я могу исправить этот код?
Спасибо за Ваше внимание.
Логика, касающаяся генерации миниатюр, неверна, но более актуальной проблемой является сохранение файла изображения. Вы пытаетесь сохранить в корне файловой системы (/users/$id/avatar.png
), вероятно, без разрешений, необходимых для этого.
Хотя вы можете сохранить обратно на путь загрузки, это не обязательно. В imagepng
просто сохраните файл по назначению (например, /var/web/app/public/uploads/$id/avatar.png
). Вы также можете использовать магическую константу __DIR__
указать путь относительно файла PHP, выполняющего выполнение.
Что касается обрезки, подумайте об использовании встроенной функции или библиотеки для создания миниатюр. Я мог бы скопировать некоторый код здесь, но другие люди много раз избивали эту проблему до смерти (и исправляли другие потенциальные проблемы, такие как прозрачность). Вы можете просмотреть документацию (и комментарии пользователей) на imagecopyresampled
, или использовать сложную библиотеку, такую как Представить.
Итак, после многократного онлайн-поиска я обнаружил, что самая большая проблема связана с пользователем, который запускает apache (www-data).
Поэтому я ввел / etc / apache2 / envvars и изменил APACHE_RUN_USER на владельца папки.
Затем я должен был сделать выборку в / etc / lib / php5, чтобы сессии работали с новым пользователем.
После этого я смог получить доступ к папке, чтобы сервер мог писать и изменять ее.
Затем я добавил в код эту часть:
$dir = "./users/$id/";
$oldumask = mask(0);
mkdir ("$dir");
chmod("$dir", 0750);
umask($oldumask);
Это было добавлено прямо перед созданием изображения png.
Затем я удалил код «move_uploaded_file» и просто использовал функцию imagepng, как предложил Джейкоб Будин:
if(!imagepng($upload, $name)) $fail .= "<h3>ERROR!<h3><br>";
Это решило все (но тот факт, что код обрезки был неправильным, но это не имеет значения).
Я все еще не уверен на 100%, как GD / PHP очень хорошо обрабатывает изображение, но это работает.
Спасибо вам всем и с Рождеством Христовым.