标准化图像的正确方式


Proper way of standardizing images

我正在构建一个使用亚马逊产品广告API的web应用程序。问题是API为每个产品返回不同大小和纵横比的图像。如果我将所有图像调整为静态宽度/高度,那么由于比例的变化,其中一些图像看起来很奇怪。这些图像将被排列成一排,每排四张。我想我只会使图像的宽度相同,同时保持长宽比相同,然后为高度设置某种最大阈值,以防API返回一些奇怪大小的图像。

但是,我想看看这里的人以前是否遇到过这种情况,他们对这个设计问题有什么想法?

这是一个多大的共同事件。我也面临着类似的问题,这就是我决定继续前进的原因。这可能不是最好的解决方案,但它对我有效

首先我得到图像的原始高度和宽度

list($width, $height) = getimagesize("path to image");

然后我找出两者的最大公约数,并将宽高比存储在变量中,如$wr$hr

然后通过比较水平方向的$wr > $hr和垂直的$hr > $wr来检查图像方向(水平或垂直)

如果是水平的,我会确保拇指大小不超过某个值,比如120px,并根据纵横比使高度对应于120px。如果方向是垂直的,也可以这样做。

我在尝试标准化徽标时遇到了同样的问题。起初,我认为我可以选择一个标准区域,并将所有图像调整到该区域,但这种策略有两个问题。首先,你必须设置高度和宽度的限制,所以有时你会得到面积较小的图像,因为它们非常宽或高。其次,这可能会让你的布局看起来很难看。在我的例子中,我在上面有一个标题,一个图像,然后在下面有文本。我意识到一个非常宽的图像会在标题和文本之间留下很大的间隙。正因为如此,我需要一个优先考虑宽度的解决方案。我的意思是,图像的宽度可以改变很多,而高度不会改变很多。不同的应用程序可能有不同的要求,但我认为我的解决方案允许任何情况,例如对高度的偏好:

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(intercept)是图像面积和纵横比之间线性关系的组成部分。

您可以使用我提供的值($slope=2500;$icpt=6000),也可以自己计算。我想让这个过程自动化一点,但由于参数非常主观,所以看起来不太实用。为了计算它们,有必要为纵横比的两个不同实例定义区域,其中纵横比为$width/$height。例如,当比率为1($width=$height)时,您可能希望面积为8000像素^2,而当比率为2($width=2*$height。有了这些值,我们就有了:

$A1 = 8000;
$A2 = 12000;
$r1 = 1;
$r2 = 2;

您可以计算斜率和截距如下:

$slope = ($A2 - $A1)/($r2 - $r1);
$icpt = $A1 - $slope*$r1;