【问题标题】:How to calculate Facebook cover offset如何计算 Facebook 封面偏移量
【发布时间】:2014-07-17 20:12:18
【问题描述】:

我一直在尝试从 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 框架中的图像相同的图像?


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

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

http://imgur.com/mwzcfUR

【问题讨论】:

    标签: facebook facebook-graph-api


    【解决方案1】:

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

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

    帧高和宽分别为 295 和 784。 “86”是实验得到的神奇数字。

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

    【讨论】:

      【解决方案2】:

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

      以下是我对活动封面的处理方式(更改 fw 和 fh 以获得不同类型的封面)。

      你需要:

      fw - Facebook 显示封面图片的宽度
      fh - Facebook 显示封面图片的高度
      nw - 从 Facebook 检索到的图像的自然宽度
      nh - 从 Facebook 检索到的图像的自然高度
      ow - 您的宽度在 UI 中重新缩小图像
      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 值将 0 到 100 从容器高度的一半 (294/2 = 147) 映射到图像高度减去容器高度的一半(高度 - 147)。
      5. 对于 1000 像素高且 offset_y 为 25 的图像,图像将沿水平线居中 323.5 像素(147 + 706 的 25%,即全高减去 Facebook 容器高度),并且需要最高值为 -176.5 像素,以匹配您在 Facebook 上看到的内容。
      6. 当然,当您从 FB 拉取图像时,它们不会那么大,但它们应该大致成比例。
      7. 此外,您需要考虑显示图像的大小,因为 CSS 中的顶部定位需要以像素为单位。百分比不起作用,因为它们是根据容器元素的高度计算的。

      【讨论】:

        【解决方案3】:

        我还得处理这个诡计,花了我一整天的时间!尽管 Knezmilos 和 Justin Harrisson 之前的回答帮助我开始了,但在我终于让它工作之前,我不得不把头撞到墙上几次。

        我使用了 2000 多个真实事件来确保每个用例都正常,尽我所能检查 FB 上的最终渲染是否完全相同,并且看起来我的代码正在完成这项工作。

        如果您是 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
          ]
        

        【讨论】:

        • 2017/21/04 更新:我制作了我的 Gem 来处理帐户封面图片。享受...
        猜你喜欢
        • 1970-01-01
        • 2018-04-13
        • 2015-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-24
        • 2021-04-10
        相关资源
        最近更新 更多