Чтобы большие изображения вписались в окно форума, их конечно же нужно уменьшить. Не каждый продвинутый, а уж тем более обыкновенный пользователь форума умеет самостоятельно уменьшать картинки, поэтому хотелось бы, чтобы при загрузке они уменьшались до нужного размера автоматически. Решением данной задачи и займемся.
Фактически, сделать ресайз можно двумя принципиально разными способами:
1-й - уменьшение картинок на стороне клиента или client-side-resize. На сервер закачивается и лежит там оригинал, но выдается пользователю в визуально уменьшенном виде с ограничениями по длине и ширине. Недостаток: занимает много места на диске, долго грузятся страницы с тяжелыми изображениями. Плюсы: Вы всегда можете скачать изображение в оригинальном размере.
2-й - уменьшение картинок на серверной стороне или server-side-resize. На сервер грузится большая картинка. Далее, если она больше определенной величины по высоте и ширине - изображение автоматически уменьшается до нужных размеров и хранится на сервере уже в таком сжатом виде. То есть, например, пользователь загружает изображение 3264х2448 пикселей и 4 Мб, а оно становится 800х600 px и 100 Мб, и уже в таком виде вложения (attachments) добавляются к сообщению. Плюсы: занимает мало место на сервере, не грузит сервер при просмотре. Минусы: обратного пути нет, уменьшилась, так уменьшилась.
Стандартные функции форума phpbb3 позволяют делать миниатюру при загрузке вложений с использованием утилиты ImageMagick, но даже если эта утилита и установлена на вашем сервере, качество таких изображений немного хромает, да к тому же при клике по миниатюре подгружается оригинал загруженного изображения, то есть большая картинка. Так что использование стандартных функций отклоняем.
Для уменьшения картинок на стороне клиента существует множество модов для phpbb: Easy Resize Posted Images - самый простой и не такой громоздкий, как остальные; Image Resizer JS; Reimg Image Resizer; Highslide Attachment MOD - изображения открываются в лайтбоксе.
Для уменьшения картинок на стороне сервера для phpBB2 есть хороший мод UploadPic. Для phpbb3 готовых модов вроде нет, но есть хак, которым я и воспользуюсь.
Хак для уменьшения картинок вложений на стороне сервера
Хак позволяет уменьшить фотографии и другие картинки физически как по ширине и длине, так и по весу при загрузке вложений на сервер.
К примеру, уменьшим размер до 800:600 px, с качеством примерно 75%.
В файле includes/functions_upload.php
перед строкой:
function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false)
вставляем с новой строки код:
/**
* Resize images with the true diemensions (800*600)
*/
function resize_images()
{
if ( $this->is_image() ) {
$limite_largeur = "800px";
$limite_hauteur = "600px";
$size = getimagesize($this->destination_file);
$largeur = $size[0];
$hauteur = $size[1];
if($hauteur > $limite_hauteur OR $largeur > $limite_largeur)
{
if($largeur > $limite_largeur)
{
$hauteur = $hauteur / ($largeur / $limite_largeur);
$largeur = $limite_largeur;
}
if($hauteur > $limite_hauteur)
{
$largeur = $largeur / ($hauteur / $limite_hauteur);
$hauteur = $limite_hauteur;
}
$destination = imagecreatetruecolor($largeur, $hauteur);
if ( $this->extension == "jpg" || $this->extension == "jpeg" ) $source = imagecreatefromjpeg($this->destination_file);
elseif ( $this->extension == "png" ) $source = imagecreatefrompng($this->destination_file);
elseif ( $this->extension == "gif" ) $source = imagecreatefromgif($this->destination_file);
imagecopyresampled($destination, $source, 0, 0, 0, 0, $largeur, $hauteur, $size[0], $size[1]);
if ( $this->extension == "jpg" || $this->extension == "jpeg" ) imagejpeg($destination, $this->destination_file,75);
elseif ( $this->extension == "png" ) imagepng($destination, $this->destination_file,75);
elseif ( $this->extension == "gif" ) imagegif($destination, $this->destination_file,75);
}
}
}
перед строкой:
phpbb_chmod($this->destination_file, $chmod);
вставляем в новую строку код:
if ( $this->is_image() )
{
$this->resize_images();
}
$limite_largeur = "800px"; - максимальная ширина изображения,
$limite_hauteur = "600px"; - максимальная высота изображения
Измените эти данные на свое усмотрение
$this->destination_file,75 - цифра показывает качество изображения. Чем она больше, тем ближе качество к оригиналу, но тяжелее картинка. Если цифру и запятую перед ней убрать вообще, качество картинки плохое, где-то процентов 50.
Чтобы увеличить объём памяти, выделяемый PHP, временно, только при загрузке файлов, сразу после:
if ( $this->is_image() ) {
добавляем:
@ini_set('memory_limit', '100M');
Но это еще не все. Если на сервере установлен nginx, его конфиг тоже нужно проверить и при необходимости модифицировать, иначе грозит ошибка 413 при загрузке вложений.
С этим хаком есть одна маленькая проблема. Если будут грузить очень большую картинку, для уменьшения которой на хостинге не хватит памяти PHP, то она не будет вставлена в пост. И не будет числиться среди потерянных. Но зато будет лежать в папке /files в своём первозданном виде. Эту папку нужно систематически проверять и со слишком большими файлами разбираться вручную. Так что лучше поставить в админке форума ограничение вложений по размеру хотя бы 8 Мб.
Если оригинал двухбитный (черно белый), то возможно некоторое увеличение размера при автоматическом уменьшении его длины и ширины, поскольку функция imagecreatetruecolor создает полноцветное изображение. Решение: замените imagecreatetruecolor на imagecreate.
Убедитесь что у вас установлена библиотека GD
Выделите под PHP ~96-128mb памяти
В настройках php проверьте значения post_max_size, upload_max_filesize
В настройках форума проверьте параметры максимального веса аттачмента и
максимальное разрешение картинок.
При необходимости этот хак можно комбинировать с модами, например, чтобы
генерировалась еще и превьюшка, а оригинал открывался в лайтбоксе. Обьединив с
Highslide, получаем достаточно красивый и удобный функционал. Во вложении
'Highslide
Attatchment Mod' version 4.1.8 Русификатор в дистрибутиве есть.
Для полного счастья осталось прилепить копирайт - водяной знак- watermark.
Ставим watermark на загружаемых вложениях.
В тот же файл includes/functions_upload.php
Перед строкой
if ( $this->extension == "jpg" || $this->extension == "jpeg" ) imagejpeg($destination, $this->destination_file, 75);
вставляем с новой строки:
$black = imagecolorallocate($destination,255,255,255);
$str = "my watermark";
imagestring($destination,5,40,30,$str, $black);
где 40,30 - координаты водяного знака по горизонтали и вертикали. Правда, watermark будет ставиться только на тех изображениях, которые были автоматически уменьшены с помощь вышеописанного хака.