CSS背景大小背后的数学是什么:封面

问题描述 投票:22回答:4

我正在创建一个“图像生成器”,用户可以上传图像并在其上添加文本和/或绘图。输出的图像是固定大小(698x450)。

在客户端,当用户上传他们的图像时,它被设置为具有背景大小:封面的698x450的div的背景。这使它很好地填补了这个区域。

最终的组合图像由PHP使用GD函数生成。我的问题是,如何在PHP中使用与在CSS中相同的方式来扩展图像。我希望PHP脚本的结果看起来像在CSS中设置图像一样。有谁知道浏览器如何使用background-size:cover计算如何适当缩放图像?我想把它翻译成PHP。

谢谢

css3 gd css
4个回答
50
投票

这是封面计算背后的逻辑。

您有四个基本值:

imgWidth // your original img width
imgHeight

containerWidth // your container  width (here 698px)
containerHeight

两个比率来自这些值:

imgRatio = (imgHeight / imgWidth)       // original img ratio
containerRatio = (containerHeight / containerWidth)     // container ratio

您想要找到两个新值:

finalWidth // the scaled img width
finalHeight

所以:

if (containerRatio > imgRatio) 
{
    finalHeight = containerHeight
    finalWidth = (containerHeight / imgRatio)
} 
else 
{
    finalWidth = containerWidth 
    finalHeight = (containerWidth / imgRatio)
}

......你有相当于背景大小:封面。


3
投票

使用background-size: cover时,它会缩放到覆盖整个背景的最小尺寸。

因此,如果它比它高,那么将其缩放直到其宽度与该区域相同。如果它比它更薄,则将其缩放直到其高度与该区域相同。

当它大于要覆盖的区域时,向下缩放直到它适合(如果高度溢出较少,则缩放到相同高度,如果宽度较小,则缩放直到相同宽度)。


3
投票

感谢mdi让我指向了正确的方向,但这似乎并不合适。这是对我有用的解决方案:

    $imgRatio = $imageHeight / $imageWidth;
    $canvasRatio = $canvasHeight / $canvasWidth;

    if ($canvasRatio > $imgRatio) {
        $finalHeight = $canvasHeight;
        $scale = $finalHeight / $imageHeight;
        $finalWidth = round($imageWidth * $scale , 0);
    } else {
        $finalWidth = $canvasWidth;
        $scale = $finalWidth / $imageWidth;
        $finalHeight = round($imageHeight * $scale , 0);
    }

3
投票

我知道这是一个非常古老的问题,但我写的答案实际上更清晰,通过在图像之间使用max和min来代替每个图像本身:

var originalRatios = {
  width: containerWidth / imageNaturalWidth,
  height: containerHeight / imageNaturalHeight
};

// formula for cover:
var coverRatio = Math.max(originalRatios.width, originalRatios.height); 

// result:
var newImageWidth = imageNaturalWidth * coverRatio;
var newImageHeight = imageNaturalHeight * coverRatio;

我喜欢这种方法,因为它非常系统 - 也许这是错误的词 - 。我的意思是你可以摆脱if语句并使其工作在更“数学公式”的方式(输入=输出,如果这是有道理的):

var ratios = {
  cover: function(wRatio, hRatio) {
    return Math.max(wRatio, hRatio);
  },

  contain: function(wRatio, hRatio) {
    return Math.min(wRatio, hRatio);
  },

  // original size
  "auto": function() {
    return 1;
  },

  // stretch
  "100% 100%": function(wRatio, hRatio) {
    return { width:wRatio, height:hRatio };
  }
};

function getImageSize(options) {
  if(!ratios[options.size]) {
    throw new Error(options.size + " not found in ratios");
  }

  var r = ratios[options.size](
    options.container.width / options.image.width,
    options.container.height / options.image.height
  );

  return {
    width: options.image.width * (r.width || r),
    height: options.image.height * (r.height || r)
  };
}

我创建了一个jsbin here,如果你想看看我的意思是系统的(它还有一个scale方法,我认为在这个答案中不需要,但对通常的其他东西非常有用)。

© www.soinside.com 2019 - 2024. All rights reserved.