I noticed that when displaying photos from Albums, Facebook on web will cleverly detect your screensize and selects the right thumbnail photo and then selects the right width and height for the img element.
I used the chrome developer tools to look at the natural and displayed width and height of the images in Facebook.
Here is an example of a photo viewed on a 20.41" x 12.8" monitor at 1600x1200 resolution
Notice how it mentions that the image src is _o.jpg suffix and the natural dimensions are 1529x2048 whereas the current image element dimensions are 432 x 578
Here is the same image on a 14 inch macbook air displaying at 1440 x 900 resolution.
This one uses the suffix _n which you cannot see clearly, but you can see that the natural dimensions are 717 x 960 whereas the current image element dimensions are 538 x 720
My reason to find out is to learn the same strategy but to use it for displaying artwork which is in the standard png or jpeg format.
How much of the strategy is implemented using css? How much in javascript?
My questions are:
- how does Facebook do this detection?
- How many thumbnails does facebook create for each original photo?
- How does Facebook determine the right width and height for the img element depending on screen size?
I believe Facebook allows a max of 2048by2048 resolution.
Other than that, I am unable to find out more.
This question is also cross-posted in Quora to gain a wider audience.
UPDATE: I am using cakephp as backend and front end I am relying on jquery and html5 conventions
I noticed that when displaying photos from Albums, Facebook on web will cleverly detect your screensize and selects the right thumbnail photo and then selects the right width and height for the img element.
I used the chrome developer tools to look at the natural and displayed width and height of the images in Facebook.
Here is an example of a photo viewed on a 20.41" x 12.8" monitor at 1600x1200 resolution
Notice how it mentions that the image src is _o.jpg suffix and the natural dimensions are 1529x2048 whereas the current image element dimensions are 432 x 578
Here is the same image on a 14 inch macbook air displaying at 1440 x 900 resolution.
This one uses the suffix _n which you cannot see clearly, but you can see that the natural dimensions are 717 x 960 whereas the current image element dimensions are 538 x 720
My reason to find out is to learn the same strategy but to use it for displaying artwork which is in the standard png or jpeg format.
How much of the strategy is implemented using css? How much in javascript?
My questions are:
- how does Facebook do this detection?
- How many thumbnails does facebook create for each original photo?
- How does Facebook determine the right width and height for the img element depending on screen size?
I believe Facebook allows a max of 2048by2048 resolution.
Other than that, I am unable to find out more.
This question is also cross-posted in Quora to gain a wider audience.
UPDATE: I am using cakephp as backend and front end I am relying on jquery and html5 conventions
Share Improve this question edited Oct 6, 2018 at 19:38 Cœur 38.7k26 gold badges203 silver badges277 bronze badges asked Sep 11, 2012 at 8:14 Kim StacksKim Stacks 10.8k37 gold badges164 silver badges300 bronze badges4 Answers
Reset to default 8 +50When you stretch the window and therefore change the size of the 'theatre' the image changes size. From this I can only assume the 'theatre' is set to a certain size(s) and the image is set to have a max-width or max-height so it expands or contracts with the size of the outer elements (the theatre). This part is done with CSS.
I think the screen size detection will have something to do with the DOMDimensions ( http://pastebin./Biz9ntMj ) and the DimensionTracking ( http://pastebin./Ys72APyL ) functions. Also any click is intercepted by the 'primer' ( https://gist.github./376039 ) script that then routes the action through AsyncRequest (if needed) and then reacts depending on the JOSN response. My screen size only shows the one size for both the link and final image ( _n.jpg ) but I assume that as if is being handled by javascript then that would be how it would work the sizes out, otherwise (if javascript is off or something) it would just go back to their best guess of a one size fits all of 720 x 960 and then using css as above to force the sizing.
Edit
About the CSS...
With CSS you can set a height (specific or relative to screen size, what ever you fancy) to a block element that contains an image and then set that image to have max-height/width
so rather than a defined height/width. That way the image will keep it's aspect ratio but still expand and contract to the allowed size within the container. An example of this can be seen here: http://jsfiddle/tV6gG
On the javascript...
When anything is clicked on the page (and javascript is running) it is caught through the 'primer' script mentioned above ( a full version can be seen here - http://pastebin./BwhKJ14d ) - (For more info on this see http://www.facebook./video/video.php?v=596368660334&ref=mf ). This script then checks the rel
attribute of the click event (see line 28) and then decides what to 'bootload' based on that attribute (see line 52). From here it loads up a beast of a function ( http://pastebin./eGgtz4dT ) that handles all of the image kind of stuff.
In this script there are a couple of functions that looks like they may have something to do with the image size, one being getCurrentImageServerSizeDimensions (see line 218). There are other about stage sizing and what not too but my guess is that one is important. As far as I know, this script will then pile a load of data and them make a different call to the server than with the regular href.
Unescaped href from source:
http://www.facebook./photo.phpfbid=10152228292295554&
set=t.516587895&type=3&src=http://sphotos-g.ak.fbcdn/hphotos-ak-
snc7/374008_10152228292295554_643067794_n.jpg&size=720,960&theater
Unescaped actual request sent to pagelet (for more info on pagelets see the above video about BigPipe) maker:
http://www.facebook./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
Whilst they do contain most of the same info you can clearly see that the request is being caught and so (if needed) any corrected information (image size) could be sent through that.
With regards to the previous scripts...
The DOMDimensions script is a collection of functions that are pretty well explained by the functions titles to be honest (getElementDimensions
, getViewportDimensions
, getViewportWithoutScrollbarDimensions
, getDocumentDimensions
and measureElementBox
). For more info on what these individual functions actually do I'd remend having a look through them and just checking out any basic javascript functions that you don't get. It doesn't look too plicated.
The DimensionTracking script just seems to call the getViewportDimensions()
and save the data generated with the /ajax/dimension_context.php
page.
If seems to reevalute the dimensions every 100 milliseconds (see line 17), on window resize (see line 18) or on window focus (see line 18).
Over all I think you could do the important stuff (minus the finding actual different images thing) by just using the CSS method above to make a massive image fit the correct stage size.
Lots of websites do this kind of thing. I'd step back from focusing too much on exactly how Facebook acplishes it, and instead on how you can acplish the same thing.
One way to achieve something similar would be to detect the user agent's screen dimensions, which you can easily do in javascript by checking the Screen object. After that, your javascript code could update the image links on the page to point to appropriately sized images that've already been generated by your CMS or framework.
In terms of determining the size that the image should be displayed, that is a simple mathematical calculation. Often the template has a bounding box size for where the image is to be displayed, so the image just needs to be scaled down such that its width and height fit within this box.
But this discussion raises the larger point: that if you are developing a website, you're likely using a CMS or at the very least some kind of development framework. It's very likely that whatever platform you're using has a plugin, or module, etc., with image caching and resizing features built in already. You should probably describe what platform you're using so people can better address your situation.
CSS can use the @Media selector to determine general width/height. You will not be able to determine the exact width/height with this method. This will give you a rough idea on which elements you might want to display. From this point on you can use relative values in order to resize the img-element. To determine the exact screensize you would have to use Javascript. In JQuery you can access the width and height of a document.
Facebook might create thumbnails according to their Media selectors' maximum size. When the size img element is resized the browser will automatically resize the image behind. If you have a look at an image from the facebook timeline, you will notice the "_n.jpg" suffix. When you change this to "_a.jpg" you will get a smaller version of this image.
Answer to your question number 1:
Facebook image resize is relatively slow. The reason for this is (this is my guess), that they use some javascript/jquery resize. You have bunch of this scripts online.
Now this is bad (if image is large this is slow). The solution for this is to use google developers Closure tools. I spent a lot of time (on several projects where I needed to do exactly what you need) figuring this out. Closure tools (or apache mod_pagespeed ), kills unnecessary pixel from your image making it small (in kb/mb). There was a session from last year Google IO, that is talking about this.
This is a link with that session.
Answer to your question number 2:
I think that they create only two thumbnails.
Answer to your question number 3:
In answer number 1 I wrote that they use some javascript/jquery code for that. Maybe this is some logic for that:
on window resize {
make div proportional resize (percent) ->
this div find image
image width height is div width height - offset
}
I am pretty sure that best way to do this resize is not to make millions thumbnails but to optimize original image, to kill pixels from it and that to do that resize with some jquery/javascript plugin.