Автор Тема: Алгоритм ресайза картинок  (Прочитано 24441 раз)

Natyuma

  • Гость
Алгоритм ресайза картинок
« : Декабря 22, 2011, 10:45:17 pm »
Поля у картинок (особенно у больших) ужасно выглядят. Хочу переделать, чтобы помимо ресайза лишнее обрезалось.

Результат выложу )

Плиииз! ))
« Последнее редактирование: Января 10, 2012, 09:57:14 pm от Natyuma »

nictboom

  • Гость
cfg/functions.php
function img_resize($src$dest$width$height$rgb$quality=100)...

Natyuma

  • Гость
Спасибо!

Natyuma

  • Гость
В админке правильно надо настроить размеры шерины и высоты
Я специализируюсь на самописных фотогалереях. Текущий алгоритм не позволяет обрезАть фотографии при закачке. Например, превьюшка должна быть горизонтальной по задумке дизайнера, а криворукий клиент закачивает вертикальную фотку. Получается, что фотка уменьшается и накладывается на фон, заданный в админке. Если фон у сайта гладкий без фактуры и градиента, то результат еще более-менее. А вот если дизайнер задумал что-то этакое... Короче, вдруг кому пригодится )) Не претендую на красивость решения, но вроде бы хорошо работает... Итак,

Обрезка изображений (crop):
1. В файл cfg/functions.php функцию img_resize полностью заменить на
function img_resize($src, $dest, $width, $height, $rgb = 0xFFFFFF, $quality = 100) {
if (!file_exists($src)) {
return false;
}

$size = getimagesize($src);

if ($size === false) {
return false;
}

$format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1));
$icfunc = 'imagecreatefrom'.$format;

if (!function_exists($icfunc)) {
return false;
}

$x_ratio = $width  / $size[0];
$y_ratio = $height / $size[1];

if ($height == 0) {

$y_ratio = $x_ratio;
$height  = $y_ratio * $size[1];

} elseif ($width == 0) {

$x_ratio = $y_ratio;
$width   = $x_ratio * $size[0];

}

$ratio       = min($x_ratio, $y_ratio);
$use_x_ratio = ($x_ratio == $ratio);

$new_width   = $use_x_ratio  ? $width  : ceil($size[0] * $ratio);
$new_height  = !$use_x_ratio ? $height : ceil($size[1] * $ratio);
$new_left    = $use_x_ratio  ? 0 : floor(($width - $new_width)   / 2);
$new_top     = !$use_x_ratio ? 0 : floor(($height - $new_height) / 2);

$isrc  = $icfunc($src);
$idest = imagecreatetruecolor($width, $height);
//  если нужны картинки с прозрачным фоном, раскомментарить
// if ($format=='png')
// {
// imageAlphaBlending($idest, false);
// imageSaveAlpha($idest, true);
// }
// else
imagefill($idest, 0, 0, $rgb);
imagecopyresampled($idest, $isrc, $new_left, $new_top, 0, 0, $new_width, $new_height, $size[0], $size[1]);

//  если нужны картинки с прозрачным фоном, раскомментарить
// if ($format=='png') imagepng($idest, $dest);
// else
imagejpeg($idest, $dest, $quality);

imagedestroy($isrc);
imagedestroy($idest);

return true;
}

 
function img_crop($src, $dest, $a, $b, $x, $y, $width, $height, $rgb = 0xFFFFFF, $quality = 100) { 

if (!file_exists($src)) { 
    return false; 


$size = getimagesize($src);
list ($w, $h) = getimagesize($src); 

if ($size === false) { 
    return false; 


$format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1)); 
$icfunc = 'imagecreatefrom'.$format; 
 
if (!function_exists($icfunc)) { 
    return false; 


$isrc  = $icfunc($src); 
$idest = imagecreatetruecolor($width, $height); 

//  если нужны картинки с прозрачным фоном, раскомментарить
// if ($format=='png')
// {
// imageAlphaBlending($idest, false);
// imageSaveAlpha($idest, true);
// }
// else
imagefill($idest, 0, 0, $rgb);

imagecopy($idest, $isrc, $a, $b, $x, $y, $w, $h); 

//  если нужны картинки с прозрачным фоном, раскомментарить
// if ($format=='png') imagepng($idest, $dest);
// else
imagejpeg($idest, $dest, $quality);

imagedestroy($isrc); 
imagedestroy($idest); 

return true; 
}
// алгоритм ресайза с обрезкой: вырезается центральная часть изображения, если картинка меньше - растянется
function image_resize_crop ($in_url, $out_url, $new_width, $new_height)
{
list ($width, $height) = getimagesize ($in_url);
if ($width / $height > $new_width / $new_height )
{
img_resize($in_url, $out_url, 0, $new_height, CONF_IMAGE_COLOR, 100);
list ($width, $height) = getimagesize ($out_url);
img_crop($out_url, $out_url, 0, 0, ($width - $new_width )/2, 0, $new_width, $new_height, CONF_IMAGE_COLOR, 100);
}
else
{
img_resize($in_url, $out_url, $new_width, 0, CONF_IMAGE_COLOR, 100);
list ($width, $height) = getimagesize ($out_url);
img_crop($out_url, $out_url, 0, 0, 0, ($height - $new_height)/2, $new_width, $new_height, CONF_IMAGE_COLOR, 100);
}

}
// алгоритм ресайза без обрезки: если закачиваемая фотка меньше, она закачается без изменения размеров.
function image_resize_nocrop ($in_url, $out_url, $new_width, $new_height)
{
list ($width, $height) = getimagesize ($in_url);
if ($width >= $new_width)
{
if ($width / $height >= $new_width / $new_height)
img_resize($in_url, $out_url, $new_width, 0, CONF_IMAGE_COLOR, 100);
else
img_resize($in_url, $out_url, 0, $new_height, CONF_IMAGE_COLOR, 100);
}
else
{
if ($height >= $new_height)
img_resize($in_url, $out_url, 0, $new_height, CONF_IMAGE_COLOR, 100);
else
img_resize($in_url, $out_url, 0, $height, CONF_IMAGE_COLOR, 100);
}

}

2. В файле includes/admin/sub/catalog_products_edit.php нужно найти все вызовы функции img_resize и заменить на image_resize_crop или image_resize_nocrop в зависимости от того, где какая функция требуется. Не забыть убрать последний параметр (CONF_IMAGE_COLOR)!

Например, у меня Фотография и Маленькая фотография обрезаются, а Большая фотография только уменьшается до размера по бОльшей стороне (все размеры указываются в админке, кроме размера картинок для корзины, а для карусели используется размер "Маленькая фотография")


P.S. Модераторы, если посчитаете нужным, перенесите тему в раздел Разработка...
« Последнее редактирование: Января 10, 2012, 10:02:45 pm от Natyuma »

nictboom

  • Гость
Re: Алгоритм ресайза картинок
« Ответ #4 : Января 10, 2012, 10:24:34 pm »
Цитировать
а для карусели используется размер "Маленькая фотография"
соглашусь. как по мне, так картинка-S.jpg это лишнее.
да и -SC.jpg тоже...
« Последнее редактирование: Января 10, 2012, 10:26:55 pm от nictboom »

Natyuma

  • Гость
Re: Алгоритм ресайза картинок
« Ответ #5 : Января 11, 2012, 02:19:36 am »
соглашусь. как по мне, так картинка-S.jpg это лишнее.
да и -SC.jpg тоже...
картинка-S.jpg не лишнее. Я делала пару магазинов на виртумарте, там нет третьего размера, и мне их не хватало. В категории - маленькая, на странице товара ужатая большая, которая по клику увеличивается до своего реального размера - не гуд, особенно если размеры дизайном жестко заданы, а большая картинка не перед закачкой не обрезана под нужное соотношение ширины к высоте.

nictboom

  • Гость
Re: Алгоритм ресайза картинок
« Ответ #6 : Января 11, 2012, 03:29:19 am »
пардон, перепутал с картинка-Н.jpg, для хитов которая. ::)
« Последнее редактирование: Января 11, 2012, 03:32:32 am от nictboom »

Оффлайн Al_Uk

  • Спец
  • ***
  • Сообщений: 247
    • Просмотр профиля
Re: Алгоритм ресайза картинок
« Ответ #7 : Января 11, 2012, 10:20:01 am »
с картинками странно другое.. альты прописываются только для маленьких картинок 220px. а при открытии большой картинки через FancyBox  альтов нет... что есть очень и очень плохо, не говоря уже о замене имени самой картинки.. (речь идет про главную картинку товара)

Natyuma

  • Гость
Re: Алгоритм ресайза картинок
« Ответ #8 : Января 11, 2012, 10:56:38 am »
ну почему же не нужная размеры картинок хитов 120 а картинка в товаре 220 и если отказаться от -Н то на чтоже его заменять?
Хиты надо делать такого же размера, как Маленькая фотография, либо добавить в админку возможность задавать размеры картинок хитов. Отдельная картинка для хитов - это уже необязательный наворот.

nictboom

  • Гость
Re: Алгоритм ресайза картинок
« Ответ #9 : Января 11, 2012, 01:37:55 pm »
Цитировать
Хиты надо делать такого же размера, как Маленькая фотография
а зачем, нужно просто использовать маленькую фотку для хитов, разница  то 130px и 150px.

Natyuma

  • Гость
Re: Алгоритм ресайза картинок
« Ответ #10 : Января 13, 2012, 04:02:49 pm »
а зачем, нужно просто использовать маленькую фотку для хитов, разница  то 130px и 150px.
Вот и я о том же!
+1 , хотя наличие "лишней" картинки вряд ли кому-то помешает.

Оффлайн Al_Uk

  • Спец
  • ***
  • Сообщений: 247
    • Просмотр профиля
Re: Алгоритм ресайза картинок
« Ответ #11 : Января 14, 2012, 09:11:02 pm »
а двумя картинками нельзя обойтись?
средняя картинка 220 px
и большая картинка родного разрешения
все маленькие картинки ресайзить из 220px на лету.. вроде нагрузка не должна быть большой
 

nictboom

  • Гость
Re: Алгоритм ресайза картинок
« Ответ #12 : Января 14, 2012, 09:16:35 pm »
можно было бы и "на лету", и использовать только большую. ведь все картинки кэшируюся.
алгоритм нужен хороший + что бы работал у большинства, а то как на прежнем форуме, у половины не пашет(у кого проблемы с gd, у кого с mod_rewrite, а у кого то ещё  РНР 4 :) ).

Оффлайн Al_Uk

  • Спец
  • ***
  • Сообщений: 247
    • Просмотр профиля
Re: Алгоритм ресайза картинок
« Ответ #13 : Января 15, 2012, 04:18:51 pm »
из одно картинки ресайзится на опенкарте.. там вроде проверенный алгоритм

SibBear

  • Гость
Re: Алгоритм ресайза картинок
« Ответ #14 : Января 15, 2012, 05:26:42 pm »
Если картинки в кешэ то нагрузки не будет.
После 100 заходов все картинки будут в кешэ