Преобразование изображений из BLOB (mysql,php,.htaccess) | Блог
Вятские Поляны

Преобразование изображений из BLOB (mysql,php,.htaccess)

Уважаемые пользователи кому не понятен заголовок можете не читать дальше :)

Появилась проблема  с местом и я решил хранить часть фотографий прямо в БД данных, что конечно немного тормозит загрузку но решает мою проблему.

Вывод изображения из базы данных всем известен и очень просто: 

header('content-type: image/jpeg');  // дальше пойдет картинка
echo $img; //Сама картинка

Но мне стала интересно преобразовывать картинку по выходу из БД. Сама идея

1. Картинка выгружается из БД

2. Если есть параметры преобразовываем размеры

3. Если картинка больше чем привев просмотр клеймим её логотипом.

И вот в этот момент не нашел в интернете сходу тему как это сделать. Честно в гугле прошел по всем ссылкам в итоге на 2 день я отрыл эту дикую функцию imagecreatefromstring -  функция создает картинку из строки ну явное отличие от imagecreatefromjpeg и других. Но она так спрятана и не описана в интернете, что моим долгом будет рассказать как все это работает.

Значит у нас изображение, максимального размера храниться в БД.

Но начнем сначала.

Загрузка файла в БД

Используем стандартную форму для загрузки изображения только в обработке вместо функции copy обрабатываем и добавляем в БД: 

$img = file_get_contents($_FILES["foto"]["tmp_name"]); //Превратим файл в строку 
$img = mysql_escape_string($img); //Без этой функции не работает 
$q = "INSERT INTO `".$baz."`.`photo` (`id`, `name`, `con`) VALUES (NULL, '".$nam."', '".$img."');"; 
mysql_query($q);

А теперь вывод, в БД храниться в поле con как видно на фото.

Все знают что браузеры не сохраняют в кеше относительные пути, это все что после  ? не будет сохраняться. Значит вариант вывода из БД в таком виде не пойдет:

img.php?id=1

А теперь представте что туда же параметры добавить

img.php?id=1&w=300&h=200

Ну точно ни когда не сохраниться и загружаться будет дольше

А к примеру вот такую картинку с радостью скушает

/photo/1.300.200.jpg

Заметили хитрость? Если нет читаем дальше.

Открываем свой .htaccess

И добиваем туда строчку данного вида:

RewriteRule ^photo/(.*) /img.php?id=$1 [L]

Переводиться как  все пути которые начинаются c photo/ и там дальше что угодно открывать файл img.php а параметру id передаем все что там есть после photo

Теперь создаем файл img.php в корне и начинаем изучать полный код, постараюсь описать все в комментариях

if ($iq = $_GET[id]) { // Принимаем данные (Стоит ещё проверить на правильность ввода, никогда не доверяйте пользователям)
$ii = explode(".",$iq); // Разбираем переменную в массив отделенные точками
//Преобразуем маску
$id = $ii[0]; //Это наша фотография
if ($ii[1] != "jpg") { $width = $ii[1]; } //Это Шерина а если окажется что jpg значит что размеры не нужны
$height = $ii[2]; //Высота
//Работаем
require_once 'config.php'; //Подключаем БД
$logo = $path.'/img/style/logo2.png'; // Это берем логотип, берем именно тут потому что для уменьшения кода используем нижу функцию header('content-type: image/jpeg'); //Картинка дальше пойдет $q=mysql_query("select con from photo where id=".$id.";"); // выбрали нужную фотографию list($con)=mysql_fetch_array($q); //В переменной con содержится фотография //Создем картинку $image = imagecreatefromstring($con); //Вот эта крутая функция, которая из строки создает картинку if ($image === false) { return false; } //Это если что то не сработало //Есть размеры if ($width != '' && $height != '') { //Если есть размеры запускам преобразователь//Считываем размеры с картинки которую взяли в БД и преобразовали $size[0] = imagesx($image); $size[1] = imagesy($image); //Нужные размеры, для логики преобразования нужно$new_height = $height;$new_width = $width;//Вычисление формы тут я ни чего не понимаю готовый код он считает соотношения и делает норм картинкуif ($size[0] < $size[1])$new_width=($size[0]/$size[1])*$height;else$new_height=($size[1]/$size[0])*$width;$new_width=($new_width > $width)?$width:$new_width;$new_height=($new_height > $height)?$height:$new_height;$image_p = @imagecreatetruecolor($new_width, $new_height); //Макет новой картинки$image_cr = $image; //Исходная картинка//Создем изображениеimagecopyresampled($image_p, $image_cr, 0, 0, 0, 0, $new_width, $new_height, $size[0], $size[1]);if ($width > 350 || $height > 250) {  //Картинка большая лепим логотипlogo($image_p,$logo); //Функция логотипа ниже} else {imagejpeg($image_p); //Картинка маленькая выводим изображениеimagedestroy($image); //Очищаем память}
} else { 
//Нету размеров
logo($image,$logo); //Надо логотип приклеить
}
}
function logo($image,$logo) {
//Получаемым размеры
$size[0] = imagesx($image); $size[1] = imagesy($image);//Берем логотип
$watermark = imagecreatefrompng($logo);//считаем размеры
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);//Смешение
$dest_x = $size[0] - 300;
$dest_y = $size[1] - 75;//Формируем
imagealphablending($image, true);
imagealphablending($watermark, true);// создаём новое изображениеimagecopy($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);//Выводим
imagejpeg($image);// освобождаем памятьimagedestroy($image);imagedestroy($watermark);  
}

ВСе работает, хочется услышать мнения по скорости работы. Так как не умею проводить тесты. И вообще логично ли так делать? Ил все таки стоит хранить уже преобразованные фотографии в БД

Поможем найти
ЯХ