代码背后的数学公式

时间:2015-11-19 22:34:27

标签: php math resize thumbnails

有谁知道与以下代码字符串相关的数学公式?

 // aspect ratio <
 $src_pos = array(0, (($new_size[1] - $thumb_height) * ($src_size[1] /$new_size[1])) / 2 );
 // aspect ratio >
 $src_pos = array((($new_size[0] - $thumb_width) * ($src_size[0] / $new_size[0])) / 2, 0);

它们位于一个更广泛的脚本中,可以从上传的图像中创建拇指:

//variables
$src_size = getimagesize($_FILES["file"]["name"]);
$thumb_width = 250;
$thumb_height = 200;
$src_aspect = round(($src_size[0] / $src_size[1]), 1);
$thumb_aspect = round(($thumb_width / $thumb_height), 1);

if ($src_aspect < $thumb_aspect){
    //higher
    $new_size = array($thumb_width,($thumb_width / $src_size[0]) * $src_size[1]);
    $src_pos = array(0, (($new_size[1] - $thumb_height) * ($src_size[1] /$new_size[1])) / 2 );
}else if($src_aspect > $thumb_aspect){
    //wider
    $new_size = array(($thumb_width / $src_size[1]) * $src_size[0], $thumb_height);
    $src_pos = array((($new_size[0] - $thumb_width) * ($src_size[0] / $new_size[0])) / 2, 0);
}else{
    //same shape
    $new_size = array($thumb_width, $thumb_height);
    $src_pos = array(0, 0);
}

if ($new_size[0] < 1) $new_size[0] = 1;
if ($new_size[1] < 1) $new_size[1] = 1;


//creation of thumb
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
imagecopyresampled($thumb, $src, 0, 0, $src_pos[0], $src_pos[1], $new_size[0], $new_size[1], $src_size[0], $src_size[1]);

我正在研究这个脚本,但是我无法理解我在这个问题开头写的两行代码背后的逻辑,所以我想知道它们与哪个数学公式有关。

1 个答案:

答案 0 :(得分:1)

您需要分别查看每个宽高比if部分,将它们混合在一起,这从开始时有点混乱(将评论添加到您的问题中)。

我认为是这样的:

// load image
$src_size = getimagesize($_FILES["file"]["name"]);
// static fixed resolution for the thumb
$thumb_width = 250; 
$thumb_height = 200;
// aspects (if the x or y size is bigger for image and thumb
$src_aspect = round(($src_size[0] / $src_size[1]), 1);
$thumb_aspect = round(($thumb_width / $thumb_height), 1);

// rescale height because the result will not exceeding thumb height in this case
if ($src_aspect < $thumb_aspect){
    $new_size = array
     (
     $thumb_width,                                 // thumb width stays as is
     ($thumb_width / $src_size[0]) * $src_size[1]  // thumb height is rescaled by image aspect
     );
    // this just compute the distance to move the thumb after rescaling so it is still centered
    $src_pos = array(0, (($new_size[1] - $thumb_height) * ($src_size[1] /$new_size[1])) / 2 );
}
// rescale width because the result will not exceeding thumb width in this case
else if($src_aspect > $thumb_aspect){
    $new_size = array
     (
     ($thumb_width / $src_size[1]) * $src_size[0],  // thumb width is rescaled by image aspect
     $thumb_height                                 // thumb height stays as is
     );
    // this just compute the distance to move the thumb after rescaling so it is still centered
    $src_pos = array((($new_size[0] - $thumb_width) * ($src_size[0] / $new_size[0])) / 2, 0);
}else{
    //same shape
    $new_size = array($thumb_width, $thumb_height);
    $src_pos = array(0, 0);
}

if ($new_size[0] < 1) $new_size[0] = 1;
if ($new_size[1] < 1) $new_size[1] = 1;


//creation of thumb
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
imagecopyresampled($thumb, $src, 0, 0, $src_pos[0], $src_pos[1], $new_size[0], $new_size[1], $src_size[0], $src_size[1]);

我希望这些评论对你来说已经足够......但是一定要让我们检查一下:

  • ( $thumb_width / $src_size[0]) * $src_size[1]

我会改用它(所以只使用整数数学)

  • ( $thumb_width * $src_size[1] ) / $src_size[0]

因此$thumb_width是指甲目标最大分辨率,$src_size[1] / $src_size[0]是图像纵横比常数小于1.0。当您更仔细地观察整条线时,它是简单的线性插值而没有偏移(起点位于(0,0)),因此结果将小于缩略图分辨率(将适合内部)并仍然匹配原始图像宽高比。

数学公式:

  • 让2个点(x0,y0)(x1,y1)代表一条线的端点。
  • 和行内
  • 的任意点(x,y)

因此,如果我们知道一个点在线的一个坐标,我们可以通过利用这样的三角形相似性来计算另一个坐标:

  • x=x0+(y-y0)*(x1-x0)/(y1-y0)
  • y=y0+(x-x0)*(y1-y0)/(x1-x0)

这称为线性插值。在您的情况(x0,y0)=(0,0)中,等式变为:

  • x=y*x1/y1
  • y=x*y1/x1

您的代码所代表的内容...... x,ynew_sizex1,y1src_size

现在位置偏移

例如,你计算它是这样的:

  • ($new_size[0] - $thumb_width) * ($src_size[0] / $new_size[0])) / 2 所以条款是:
  • ($new_size[0] - $thumb_width)是新缩略图分辨率和原始缩略图分辨率之间的空白区域
  • ($new_size[0] - $thumb_width)/2是您需要移动已调整大小的缩略图以将其置于原始缩略图分辨率的中间位置
  • ($src_size[0] / $new_size[0])只是将此偏移量从缩略图坐标转换为图像坐标系

当你把所有的东西放在一起时,你得到的位置有点在图像之外(所以缺少的数据用背景颜色填充)所以当从这个位置复制从图像到缩略图的数据时,你获得了以空白空间为中心的重新缩放的缩略图图像在重新缩放的轴周围...(除非我遗漏了什么)