我在尝试标准化徽标时遇到了同样的问题。起初,我认为我可以选择一个标准区域并将所有图像调整到该区域,但该策略存在两个问题。首先,您必须设置高度和宽度的限制,因此有时您会得到面积较小的图像,因为它们非常宽或高。其次,这可能会使您的布局看起来很难看。就我而言,我在顶部有一个标题,一个图像,然后是下面的文本。我意识到一个非常宽的图像会在标题和文本之间留下很大的差距。因此,我需要一个优先考虑宽度的解决方案。我的意思是,图像可以在宽度上发生很大变化,而高度不会发生很大变化。不同的应用程序可能有不同的要求,但我认为我的解决方案也允许任何情况,例如对高度的偏好:
function width_to_height($width, $slope, $icpt){
if ($width == 0){
return FALSE;
}
return floor(($icpt + sqrt(pow($icpt, 2) + 4*$slope*pow($width, 2)))/(2*$width));
}
function ratio_to_height($ratio, $slope, $icpt){
if ($ratio == 0){
return FALSE;
}
$area = $ratio*$slope + $icpt;
return floor(sqrt($area/$ratio));
}
function calc_dims($width, $height, $max_w=168, $max_h=100){
$slope = 2500;
$icpt = 6000;
$ratio = $width/$height;
$max_ratio = $max_w/$this->width_to_height($max_w, $slope, $icpt);
if ($ratio > $max_ratio){
$ht = floor($max_w/$ratio);
return array('width' => $max_w, 'height' => $ht);
}
$ht = $this->ratio_to_height($ratio, $slope, $icpt);
if ($ht > $max_h){
$wd = floor($max_h*$ratio);
return array('width' => $wd, 'height' => $max_h);
}
$wd = floor($ht*$ratio);
return array('width' => $wd, 'height' => $ht);
}
主函数是调用其他两个函数的 calc_dims()。因为我几乎总是使用类,所以这些函数是用“this->”运算符调用的。如果你不使用类,你可以简单地删除操作符。
你可以看到我硬编码了一些变量。 (在我的实际应用程序中,这些是从配置文件中调用的。) $max_w 和 $max_h 作为图像的最大高度和宽度是非常不言自明的。但是 $slope 和 $icpt 可能有点难以理解。正如您在 ratio_to_height() 函数中看到的那样,$slope 和 $icpt(截距)是图像的面积和纵横比之间呈线性关系的分量。
您可以使用我提供的值 ($slope = 2500; $icpt = 6000),也可以自己计算。我想过让这个过程自动化一点,但由于参数非常主观,它似乎不太实用。为了计算它们,有必要为纵横比的两个不同实例定义区域,其中比率为 $width/$height。例如,当比率为 1($width = $height)时,您可能希望面积为 8000 像素^2,而当比率为 2($width = 2*$height)时,面积可能为 12000 像素^ 2.有了这些值,我们就有了:
$A1 = 8000;
$A2 = 12000;
$r1 = 1;
$r2 = 2;
您可以按如下方式计算斜率和截距:
$slope = ($A2 - $A1)/($r2 - $r1);
$icpt = $A1 - $slope*$r1;