10 дек. 2008 г.

PHP+GD: масштабирование изображений

частенько перед программистом стоит задача масштабирования загруженной пользователем картинки...

обычно используют масштабирование до "предельного прямоугольника". например, вот так:

но иногда необходимо получить картинку с чётко заданными шириной и высотой. и не обязательно будет совпадать расположение картинки до и после обработки (вертикально/горизонтально). например, вот так:


сейчас для решения этой задачи есть масса вариантов решений на аяксе (например, как описано здесь).
одно маленькое "но": требуется вмешательство человека - пользователя либо админа.

тем не менее, часто бывает достаточно такого правила: если у нас портальное размещение изображения, то обрезка идёт от центра, если же положение изображения вертикальное - то обрезка делается по верхнему краю

недавно столкнулись с такой вот задачей.
оказалось, что алгоритм-то понятен, а вот готовых простых решений - не так уж и много.
в результате - родилась данная процедурка.

сперва хотел всё расписать и прокомментировать...
а потом передумал )))
кому надо - сам поймёт. ну или спросит ;)

function imgCropResize($s_src, $s_dest, $i_th_width, $i_th_height)
{
// 0)
$a_img_size = getimagesize($s_src);
$i_curr_width = $a_img_size[0];
$i_curr_height = $a_img_size[1];

// 1)
$Ww = $i_curr_width/$i_th_width;
$Hh = $i_curr_height/$i_th_height;

if ( $Ww > $Hh )
{
$r_min = $Hh;
}
else
{
$r_min = $Ww;
}

// 2)
$i_crop_width = round($i_th_width * $r_min);
$i_crop_height = round($i_th_height * $r_min);

if ($i_curr_width == $i_crop_width)
{
$i_start_x = 0;
$i_tn_width = $i_crop_width;

$i_start_y = 0;
$i_tn_height = $i_crop_height;
}
else
{
$i_start_y = 0;
$i_tn_width = $i_crop_width;

$i_start_x = ($i_curr_width - $i_crop_width)/2;
$i_tn_height = $i_crop_height;
}

// 3)
$img_src1 = imagecreatefromjpeg($s_src);
$img_dst1 = imagecreatetruecolor($i_tn_width, $i_tn_height);

imagecopyresampled($img_dst1, $img_src1, 0, 0, $i_start_x, $i_start_y, $i_tn_width, $i_tn_height, $i_crop_width, $i_crop_height);

imagedestroy($img_src1);

// 4)
$i_curr_width = $i_tn_width;
$i_curr_height = $i_tn_height;

$r_x_ratio = $i_th_width / $i_curr_width;
$r_y_ratio = $i_th_height / $i_curr_height;

if ( ($i_curr_width <= $i_th_width) && ($i_curr_height <= $i_th_height) )
{
$i_tn_width = $i_curr_width;
$i_tn_height = $i_curr_height;
}
elseif (($r_y_ratio * $i_curr_width) < $i_th_width)
{
$i_tn_width = round($r_y_ratio * $i_curr_width);
$i_tn_height = $i_th_height;
}
elseif (($r_x_ratio * $i_curr_height) < $i_th_height)
{
$i_tn_height = round($r_x_ratio * $i_curr_height);
$i_tn_width = $i_th_width;
}
else
{
$i_tn_width = ceil($r_y_ratio * $i_curr_width);
$i_tn_height = $i_th_height;
}

// 5)
$img_src2 = $img_dst1;
$img_dst2 = ImageCreateTrueColor($i_tn_width, $i_tn_height);

imagecopyresampled($img_dst2, $img_src2, 0, 0, 0, 0, $i_tn_width, $i_tn_height, $i_curr_width, $i_curr_height);

imagejpeg($img_dst2, $s_dest, 100);
imagedestroy($img_src2);
imagedestroy($img_dst2);
}

пример вызова:
imgCropResize('2.jpg', '2_th.jpg', 100, 200);
вот как-то так ...

1 комментарий:

Internet Map