Правильный способ нанесения водяных знаков и хранение & amp; отображение изображений в переполнении стека

Я создаю веб-систему, которая будет размещать множество изображений высокого разрешения, и они будут доступны для продажи. Конечно, я никогда не буду отображать изображение высокого разрешения, вместо этого при просмотре люди увидят только изображение с низким разрешением и водяными знаками. В настоящее время рабочий процесс выглядит следующим образом:

PHP-скрипт обрабатывает загрузку изображений в высоком разрешении, когда изображение загружается, оно автоматически масштабируется до изображения с низким разрешением, а также миниатюрного изображения, и оба файла сохраняются на сервере (водяной знак не добавляется).

Когда люди просматривают, страница отображает миниатюру изображения, при щелчке она увеличивает и отображает низкое изображение с водяным знаком. В настоящее время я применяю водяной знак на лету, когда открывается низкое изображение.

Мой вопрос, каков правильный путь:

1) Должен ли я сохранить 2-ю копию изображения с низким разрешением с миниатюрой, только при первом доступе к нему? Я имею в виду, если кто-то получит доступ к изображению, я добавлю водяной знак на лету, а затем отобразить изображение & сохранить его на сервере. В следующий раз, когда к копии с водяным знаком будет добавлено то же изображение, просто отобразите копию wm, в противном случае нанесите водяной знак на лету. (в случае изменения watermark.png просто удалите изображения с водяными знаками, и они будут воссозданы при доступе).

2) Должен ли я продолжать применять водяные знаки на лету, как я делаю сейчас.

Мой самый большой вопрос, насколько велика разница между PHP file_exists()и добавление водяного знака к изображению, что-то вроде:

$image = new Imagick();
$image->readImage($workfolder.$event . DIRECTORY_SEPARATOR . $cat . DIRECTORY_SEPARATOR .$mit);
$watermark = new Imagick();
$watermark->readImage($workfolder.$event . DIRECTORY_SEPARATOR . "hires" . DIRECTORY_SEPARATOR ."WATERMARK.PNG");
$image->compositeImage($watermark, imagick::COMPOSITE_OVER, 0, 0);

Все изображения с низким разрешением имеют размер 1024×1024, JPG с настройкой качества 45%, и все ненужные фильтры удалены, поэтому размер файла изображения с низким разрешением составляет около 40–80 КБ.

Это как-то связано с этот вопрос, только масштаб и сценарии немного отличаются.

Я работаю на выделенном сервере (Xeon E3-1245v2), 32 ГБ оперативной памяти, 2 ТБ хранилища), сайт не имеет большого трафика в целом, но время от времени имеет ОГРОМНЫЕ скачки. Когда изображения выпускаются, мы получаем несколько тысяч обращений в час, когда люди просматривают изображения, скачивают, покупают и т. Д. Поэтому, при обычном использовании я уверен, что генерация на лету — это правильный подход, я немного волнуюсь о пиковом периоде.

Необходимо отметить, что я использую библиотеку ImageMagick для обработки изображений, а не GD.

Спасибо за ваш вклад.

ОБНОВИТЬ

Ни в одном из ответов нет полного комплексного решения, но это хорошо, так как я никогда не искал этого. Это было трудное решение, кого принять, а кого назначить награду.

Решение @ Ambroise-Maupate — это хорошо, но, тем не менее, это работа на PHP.

@Hugo Delsing предлагает использовать веб-сервер для обслуживания кэшированных файлов, снижая количество обращений к PHP-сценарию, что будет означать меньшее использование ресурсов, с другой стороны, это не очень удобно для хранения.

Я буду использовать решение смешанного слияния из 2 ответов, передавая задание CRON для удаления мусора.

Спасибо за указания.

4

Решение

Лично я бы создал поддомен / поддомен без файлов cookie в виде CDN, чтобы обрабатывать изображения такого типа. Основными причинами являются:

  1. Изображения создаются только один раз
  2. Созданы только доступные изображения
  3. После создания изображение подается из кэша и работает намного быстрее.

Первым шагом будет создание веб-сайта на поддомене, который указывает на пустую папку. Используйте настройки IIS / Apache или что-то еще, чтобы отключить сеансы для этого нового веб-сайта. Также установите несколько длинных заголовков кэширования на сайте, потому что контент не должен меняться

Вторым шагом будет создание .htaccess файл, содержащий следующее.

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)   /create.php?path=$1  [L]

Это гарантирует, что если кто-то получит доступ к существующему изображению, он покажет изображение непосредственно без PHP мешая. Каждый несуществующий запрос будет обработан create.php скрипт, который является следующей вещью, которую вы должны добавить.

<?php
function NotFound()
{
if (!headers_sent()) {
$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
header($protocol . ' 404 Not Found');
echo '<h1>Not Found</h1>';
exit;
}
}

$p = $_GET['path'];

//has path
if (strlen($p)<=1)
NotFound();

$clean = explode('?', $p);
$clean = explode('#', $clean[0]);
$params = explode('/', substr($clean[0], 1)); //drop first /

//I use a check for two, because I dont allow images in the root folder
//I also use the path to determine how it should look
//EG: thumb/125/90/imagecode.jpg
if (count($params)<2)
NotFound();

$type = $params[0];

//I use the type to handle different methods. For this example I only used the full sized image
//You could use the same to handle thumbnails or cropped/watermarked
switch ($type) {
//case "crop":if (Crop($params)) return; else break;
//case "thumb":if (Thumb($params)) return; else break;
case "image":if (Image($params)) return; else break;
}
NotFound();
?>
<?php
/*
Just some example to show how you could create a responds
Since you already know how to create thumbs, I'm not going into details

Array
(
[0] => image
[1] => imagecode.JPG
)
*/
function Image($params) {
$tmp = explode('.', $params[1]);
if (count($tmp)!=2)
return false;

$code = $tmp[0];//WARNING!! SQL INJECTION
//USE PROPER DB METHODS TO GET REALPATH, THIS IS JUST EXAMPLE
$query = "SELECT realpath FROM images WHERE Code='".$code."'";
//exec query here to $row
$realpath = $row['realpath'];$f = file_get_contents($realpath);

if (strlen($f)<=0)
return false;

//create folder structure
@mkdir($params[0]);

//if you had more folders, continue creating the structure
//@mkdir($params[0].'/'.$params[1]);

//store the image, so a second request won't access this script
file_put_contents($params[0].'/'.$params[1], $f);

//you could directly optimize the image for web to make it even better
//optimizeImage($params[0].'/'.$params[1]);

//now serve the file to the browser, because even the first request needs to show the image
$finfo = finfo_open(FILEINFO_MIME_TYPE);
header('Content-Type: '.finfo_file($finfo, $params[0].'/'.$params[1]));

echo $f;

return true;
}
?>
4

Другие решения

Я бы посоветовал вам создавать изображения с водяными знаками на лету и кэшировать их в то же время, что и все.

Тогда вы могли бы создать уборщик мусора PHP скрипт, который будет выполняться каждый день (используя хрон). Этот скрипт будет просматривать вашу папку кеша для чтения каждого изображения время доступа. Это можно сделать с помощью fileatime() PHP метод. Тогда когда кешируется WM изображение не было доступно в течение 24 или 48 часов, просто удалите его.

С этим методом вы можете справиться колос периоды, поскольку изображения кэшируются по первому запросу. И вы сэкономите место на жестком диске, так как ваш скрипт сборки мусора удалит для вас неиспользуемые изображения.

Этот метод будет работать только если ваш раздел сервера имеет время обновления включены.

Увидеть http://php.net/manual/en/function.fileatime.php

5

Для большинства сценариев ленивое применение водяного знака, вероятно, имело бы смысл (генерировать изображение с водяным знаком на лету по запросу, а затем кэшировать результат), однако, если у вас есть большие всплески спроса, вы сами создаете механизм для DOS: создайте версию с водяным знаком на загрузить.

1

Учитывая емкость вашего жесткого диска и количество пиков.

Я бы создал изображение с водяными знаками только в том случае, если оно просматривается (так что да, на лету). Таким образом, вы не используете много места с кучей файлов, которые можно просматривать или не просматривать.

Я бы не стал использовать миниатюры водяных знаков, я бы сделал фильтр, который имитирует водяные знаки и защищает от сохранения. Этот фильтр будет применяться ко всем эскизам без создания второго изображения.

Таким образом, все ваши пиктограммы с водяными знаками (подделка с другим элементом на вершине).

Затем, если один из этих эскизов просматривается, он создает изображение с водяным знаком (только один раз), поскольку после его создания вы загружаете новое изображение с водяным знаком.

Это был бы самый эффективный способ справиться с вашим жестким диском и Pikes.

Другой вариант — обновить хостинг. Godaddy предлагает неограниченное хранилище и пропускную способность около 50 $ в год.

0
По вопросам рекламы [email protected]