如何计算Facebook封面偏移量

时间:2014-07-17 20:12:18

标签: facebook facebook-graph-api

我一直试图从Facebook获取一些活动封面图片并在我的网站上显示。现在,人们可以上传各种尺寸和宽高比的图像,Facebook会调整它的大小,并允许它们将图像置于784 * 295帧的中心。如果您查询Facebook API以获取封面图片,这就是您所获得的:

"cover": {
    "cover_id": 300822420082720,
    "offset_x": 0,
    "offset_y": 73,
    "source": "https://fbcdn-sphotos-b-a.akamaihd.net/hphotos-ak-xfp1/t1.0-9/10273881_300822420082715_6723919589261017620_n.jpg"
}

“源”是指原始未调整大小/非居中图像的链接。所以我需要调整它/剪切它以使它看起来与Facebook事件页面完全相同。

所以问题是 - 我如何应用offset_x / offset_y来获得与784 * 295 Facebook框架中相同的图像?


我找到了以下解决方案,其中没有一个是正确的:

我已经测试了所有这些,以及更多,在几张封面图片上,其中一张如下图所示。调整大小时(如Facebook一样)下面的图像是784 * 522,图像帧总是784 * 295,我得到的offset_y是73,并且距图片顶部的距离(在Facebook上测量)是193px。我不能得到的是如何使用offset_y(73)来获得从顶部(193)偏移的像素数。

http://imgur.com/mwzcfUR

3 个答案:

答案 0 :(得分:2)

所以,最后,我无法在任何地方找到这个问题的答案,但我能够使用实验方法达到令人满意的精度,即创建我自己的事件并测试几个封面页一次移动几个像素。计算需要应用于FB封面图像以获得与Facebook中使用的帧相同的帧的偏移像素数的公式如下:

$pixelsFromAbove = (($imageHeight - $frameHeight) / 86 ) * $offset_y;
$pixelsFromLeft = (($imageWidth - $frameWidth) / 86 ) * $offset_y;

框架高度和宽度分别为295和784。 “86”是实验获得的神奇数字。

此解决方案适用于2.1版本的FB API。

答案 1 :(得分:2)

在上面链接的解决方案中,第三个是最接近100%准确的解决方案(可能很适合他的用例)。

以下是我为活动封面制作的方法(为不同类型的封面改变fw和fh)。

你需要:

fw - Facebook显示封面图片的宽度
fh - Facebook显示封面图片的高度
nw - 从Facebook检索的图像的自然宽度 nh - 从Facebook检索到的图像的自然高度 ow - 您在用户界面中缩小图片的宽度
oy - 封面照片的offset_y值

顶部偏移的公式(以像素为单位)是:

- (oy * ow / 100)*((nh / nw) - (fh / fw))

以下是我在JavaScript中实现它的方法:

self.changeOffsetY = function(element, eventCover) {
    if (eventCover === true) {
        var fw = 826;
        var fh = 294;
    } else {
        var fw = 828;
        var fh = 315;
    }

    var nw = element.naturalWidth;
    var nh = element.naturalHeight;
    var ow = element.offsetWidth;
    var oy = element.dataset.offsety;

    var top = (oy * ow / 100) * ((nh / nw) - (fh / fw));

    element.style.top = -top + 'px';
};

公式只是算法的简化。

直观地说,你可以这样理解:

  1. 封面照片以Facebook上的容器形式显示。对于活动 封面,它们目前是826x294像素。
  2. 上传图像并将其重新定位时,offset_y值为0.
  3. 当您尽可能低地重新定位时,offset_y值为100.
  4. 这意味着offset_y值从容器高度的一半(294/2 = 147)映射0到100,到图像的高度减去容器高度的一半(高度 - 147)。
  5. 对于1000px高且offset_y为25的图像,图像将沿着水平线居中323.5px(147 + 25%的706,即全高度减去Facebook容器高度),并且需要最高值为-176.5像素,与您在Facebook上看到的相符。
  6. 当然,当你从FB中提取图像时,它们并不是那么大,但它们应该大致成比例。
  7. 此外,您需要考虑显示图像的大小,因为CSS中的顶部定位需要以像素为单位。百分比不起作用,因为它们将根据容器元素的高度计算。

答案 2 :(得分:1)

我也不得不在这个诡计上工作,这花了我一整天!虽然Knezmilos和Justin Harrisson先前的答案帮助我开始,但在我终于开始工作之前,我不得不将头撞到墙壁上几次。

我使用了超过2 000个真实事件来确保每个用例都没问题,检查FB上的最终渲染完全相同,尽可能多,看起来我的代码正在完成工作。 / p>

如果您是Rails用户,对您来说是个好消息,我将这些硬件提取到Gem:facebook_cover_resize。如果你正在使用另一个堆栈并且你只对原始算法感兴趣,那么它就是(Ruby代码,但你会得到这个想法):

  ow = FINAL_OUTPUT_WIDTH.to_f
  oh = (ow / 1.91)
  nw = ORIGINAL_WIDTH.to_f
  nh = ORIGINAL_HEIGHT.to_f
  ox = OFFSET_X.to_f
  oy = OFFSET_Y.to_f

  if ox == 0 && oy == 0
    w = ow
    h = nh * (ow / nw)
    if h < oh
      h = oh
      w = nw * (oh / nh)
      offset_x = ow - w
      offset_y = 0
    else
      offset_x = 0
      if w < h
        offset_y = 0
      else
        offset_y = oh - h
      end
    end
  else
    if oy > 0
      w = ow
      h = nh * (ow / nw)
      offset_x = 0
      offset_y = (oh - h) * (oy / 100.0)
      if h < oh
        h = oh
        w = nw * (oh / nh)
        offset_x = (ow - w) / 2
        offset_y = 0
      end
    elsif ox > 0
      h = oh
      w = nw * (oh / nh)
      offset_x = (ow - w) / 2
      offset_y = 0
    else
      w = ow
      h = nh * (ow / nw)
      offset_x = 0
      offset_y = 0
    end
  end

  out = [
    offset_y.ceil,
    offset_x.ceil,
    w.ceil,
    h.ceil
  ]