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

ant*_*ver 22 css gd css3

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

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

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

谢谢

mdd*_*ddw 50

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

您有四个基本值:

imgWidth // your original img width
imgHeight

containerWidth // your container  width (here 698px)
containerHeight
Run Code Online (Sandbox Code Playgroud)

两个比率来自这些值:

imgRatio = (imgHeight / imgWidth)       // original img ratio
containerRatio = (containerHeight / containerWidth)     // container ratio
Run Code Online (Sandbox Code Playgroud)

您想要找到两个新值:

finalWidth // the scaled img width
finalHeight
Run Code Online (Sandbox Code Playgroud)

所以:

if (containerRatio > imgRatio) 
{
    finalHeight = containerHeight
    finalWidth = (containerHeight / imgRatio)
} 
else 
{
    finalWidth = containerWidth 
    finalHeight = (containerWidth / imgRatio)
}
Run Code Online (Sandbox Code Playgroud)

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

  • 不知道为什么,但我必须将最后一行改为`finalHeight =(containerWidth*imgRatio)`才能正常使用我的代码 (13认同)

pga*_*mou 13

我知道这是一个非常古老的问题,但我写的答案实际上更清晰,通过对图像之间的比率使用 max 和 mins 而不是每个图像本身:

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;
Run Code Online (Sandbox Code Playgroud)

我喜欢这种方法,因为它非常系统——也许是错误的词——。我的意思是你可以去掉这些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)
  };
}
Run Code Online (Sandbox Code Playgroud)

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


ant*_*ver 5

感谢 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);
    }
Run Code Online (Sandbox Code Playgroud)