13

我注意到,当显示相册中的照片时,网络上的 Facebook 会巧妙地检测您的屏幕尺寸并选择正确的缩略图照片,然后为 img 元素选择正确的宽度和高度。

我使用 chrome 开发者工具查看 Facebook 中图像的自然显示宽度和高度。

这是在 20.41" x 12.8" 显示器上以 1600x1200 分辨率查看的照片示例

请注意它如何提到图像 src 是 _o.jpg 后缀,自然尺寸是 1529x2048,而当前图像元素尺寸是 432 x 578

这是在 14 英寸 macbook air 上以 1440 x 900 分辨率显示的相同图像。

这个使用了你看不清楚的后缀 _n,但是你可以看到自然尺寸是 717 x 960 而当前图像元素尺寸是 538 x 720

我发现的原因是学习相同的策略,但使用它来显示标准 png 或 jpeg 格式的艺术品。

有多少策略是使用 css 实现的?javascript多少钱?

我的问题是:

  1. Facebook 如何进行这种检测?
  2. facebook 为每张原始照片创建多少个缩略图?
  3. Facebook 如何根据屏幕大小确定 img 元素的正确宽度和高度?

我相信 Facebook 最多允许2048×2048 分辨率。

除此之外,我无法找到更多信息。

这个问题也在 Quora 中交叉发布,以获得更广泛的受众。

更新: 我使用 cakephp 作为后端和前端我依赖 jquery 和 html5 约定

4

4 回答 4

8

当您拉伸窗口并因此更改“剧院”的大小时,图像会更改大小。由此我只能假设“剧院”设置为特定大小,并且图像设置为具有最大宽度或最大高度,因此它会随着外部元素(剧院)的大小而扩展或收缩. 这部分是用 CSS 完成的。

我认为屏幕尺寸检测与 DOMDimensions ( http://pastebin.com/Biz9ntMj ) 和 DimensionTracking ( http://pastebin.com/Ys72APyL ) 函数有关。此外,任何点击都会被“primer”(https://gist.github.com/376039)脚本拦截,然后通过 AsyncRequest(如果需要)路由操作,然后根据 JOSN 响应做出反应。我的屏幕尺寸只显示链接和最终图像( _n.jpg )的一种尺寸,但我假设好像是由 javascript 处理的,那么这就是它如何处理尺寸,否则(如果 javascript 关闭或一些东西)它只会回到他们对一个尺寸适合所有 720 x 960 的最佳猜测,然后使用上面的 css 来强制调整大小。

编辑

关于 CSS...
使用 CSS,您可以为包含图像的块元素设置高度(特定或相对于屏幕大小,无论您喜欢什么),然后将该图像设置为具有max-height/width此高度/宽度,而不是定义的高度/宽度。这样,图像将保持其纵横比,但仍会扩展和收缩到容器内允许的大小。可以在这里看到一个例子:http: //jsfiddle.net/tV6gG

在 javascript 上...
当在页面上单击任何内容(并且 javascript 正在运行)时,它会通过上面提到的“primer”脚本被捕获(可以在这里看到完整版本 - http://pastebin.com/BwhKJ14d) - (有关这方面的更多信息,请参阅http://www.facebook.com/video/video.php?v=596368660334&ref=mf)。该脚本然后检查rel点击事件的属性(参见第 28 行),然后根据该属性决定要“引导加载”的内容(参见第 52 行)。从这里它加载了一个处理所有图像类型的东西的功能( http://pastebin.com/eGgtz4dT )的野兽。

在这个脚本中,有几个函数看起来可能与图像大小有关,其中一个是 getCurrentImageServerSizeDimensions(参见第 218 行)。还有其他关于舞台尺寸的东西,但我猜一个很重要。据我所知,该脚本随后将编译大量数据,并且它们对服务器的调用与使用常规 href 不同。

来自源的未转义href:

http://www.facebook.com/photo.phpfbid=10152228292295554&
set=t.516587895&type=3&src=http://sphotos-g.ak.fbcdn.net/hphotos-ak-
snc7/374008_10152228292295554_643067794_n.jpg&size=720,960&theater

发送到 pagelet 的未转义实际请求(有关 pagelet 的更多信息,请参见上面有关 BigPipe 的视频)制造商:

http://www.facebook.com/ajax/pagelet/generic.php/PhotoViewerInitPagelet?
ajaxpipe=1&ajaxpipe_token=AXhGMa1SEXnChIug&no_script_path=1&data=
{"fbid":"10152228292295554","set":"t.516587895","type":"3",
"size":"720,960","theater":null,"firstLoad":true,"ssid":1354797924833}
&__user=6462456246&__a=1&__adt=2

虽然它们确实包含大部分相同的信息,但您可以清楚地看到请求正在被捕获,因此(如果需要)可以通过它发送任何更正的信息(图像大小)。

关于前面的脚本...... DOMDimensions 脚本是一组函数,
老实说,函数标题(、、、和)很好地解释了getElementDimensions这些函数。有关这些单独功能实际作用的更多信息,我建议您查看它们并检查您没有获得的任何基本 javascript 功能。它看起来并不太复杂。 DimensionTracking 脚本似乎只是调用并保存页面生成的数据。 如果似乎每 100 毫秒(参见第 17 行)、窗口调整大小(参见第 18 行)或窗口焦点(参见第 18 行)重新评估尺寸。 getViewportDimensionsgetViewportWithoutScrollbarDimensionsgetDocumentDimensionsmeasureElementBox
getViewportDimensions()/ajax/dimension_context.php



总而言之,我认为你可以通过使用上面的 CSS 方法来做重要的事情(减去寻找实际不同的图像的事情),以使大量图像适合正确的舞台尺寸。

于 2012-12-06T03:38:20.813 回答
3

很多网站都在做这种事情。我不会过多地关注 Facebook 是如何完成它的,而是关注你如何完成同样的事情。

实现类似功能的一种方法是检测用户代理的屏幕尺寸,您可以通过检查 Screen 对象在 javascript 中轻松完成。之后,您的 javascript 代码可以更新页面上的图像链接,以指向已由您的 CMS 或框架生成的适当大小的图像。

在确定图像应该显示的大小方面,这是一个简单的数学计算。通常,模板具有用于显示图像的边界框大小,因此只需将图像按比例缩小,使其宽度和高度适合该框。

但是这个讨论提出了一个更大的问题:如果你正在开发一个网站,你可能会使用一个 CMS 或者至少是某种开发框架。您使用的任何平台很可能都有一个插件或模块等,并且已经内置了图像缓存和调整大小功能。您可能应该描述您正在使用的平台,以便人们可以更好地解决您的情况。

于 2012-12-12T00:09:29.617 回答
1

CSS 可以使用@Media 选择器来确定一般宽度/高度。您将无法使用此方法确定确切的宽度/高度。这将使您大致了解可能要显示的元素。从此时起,您可以使用相对值来调整 img 元素的大小。要确定确切的屏幕尺寸,您必须使用 Javascript。在 JQuery 中,您可以访问文档的宽度和高度

Facebook 可能会根据其媒体选择器的最大尺寸创建缩略图。当 img 元素的 size 调整大小时,浏览器会自动调整后面的图像大小。如果您查看 facebook 时间线中的图像,您会注意到“_n.jpg”后缀。当您将其更改为“_a.jpg”时,您将获得该图像的较小版本。

于 2012-09-11T09:29:26.640 回答
0

回答您的问题 1:

Facebook 图像调整大小相对较慢。原因是(这是我的猜测),他们使用了一些 javascript/jquery 调整大小。你有一堆这样的脚本在线。

现在这很糟糕(如果图像很大,这很慢)。解决这个问题的方法是使用谷歌开发者的 Closure 工具。我花了很多时间(在我需要做你需要的几个项目上)来解决这个问题。关闭工具(或 apache mod_pagespeed),从图像中消除不必要的像素,使其变小(以 kb/mb 为单位)。去年有一个 Google IO 会议,就是在讨论这个问题。

这是与该会话的链接。

回答你的问题2:

我认为他们只创建了两个缩略图。

回答您的问题 3:

第 1 个答案中,我写道他们为此使用了一些 javascript/jquery 代码。也许这是一些逻辑:

on window resize { 
  make div proportional resize (percent) -> 
  this div find image
  image width  height is div width height - offset
}

我很确定进行此调整大小的最佳方法不是制作数百万个缩略图,而是优化原始图像,消除其中的像素,并使用一些 jquery/javascript 插件来调整大小。

于 2012-12-08T17:30:43.547 回答