21

When loading the Facebook feeds from one page, if a picture exist in the feed, I want to display the large picture.

How can I get with the graph API ? The picture link in the feed is not the large one.

Thanks.

1
  • The current answer is not valid any more. Please update your chosen answer. @Benjamin Kuijten has the right answer now. Commented Feb 18, 2015 at 8:55

9 Answers 9

45

The Graph API photo object has a picture connection (similar to that the user object has):

“The album-sized view of the photo. […] Returns: HTTP 302 redirect to the URL of the picture.”

So requesting https://graph.facebook.com/{object-id-from-feed}/picture will redirect you to the album-sized version of the photo immediately. (Usefull not only for displaying it in a browser, but also if f.e. you want to download the image to your server, using cURL with follow_redirect option set.)


Edit:

Beginning with API v2.3, the /picture edge for feed posts is deprecated.
However, as a field the picture can still be requested – but it will be a small one.

But full_picture is available as well.

So /{object-id-from-feed}?fields=picture,full_picture can be used to request those, or they can be requested directly with the rest of feed data, like this /page-id/feed?fields=picture,full_picture,… (additional fields, such as message etc., must be specified the same way.)

5
  • Worked form me. No need to api facebook for each post :)
    – Marcelo
    Commented Jul 31, 2013 at 21:00
  • This is the real deal. Don't mess with absolute file url's Commented Dec 10, 2014 at 18:48
  • I was hoping there was such a setting. Works like a charm. Thanks!
    – circlecube
    Commented Nov 3, 2015 at 15:48
  • You're great! I've wasted hours of searching but nobody else mentioned the mystical full_picture param Commented Jul 4, 2017 at 8:26
  • full_picture has two problems: (1) It only fetches a single image, when some posts have multiple images attached, and (2) It only returns a 720px wide image (at least on the company Facebook Page I tested it on) and not the higher resolution image. Instead you need to find the actual ID of the image/attachment itself and then ask the API for /IMAGE_ID_HERE?fields=images.
    – Simon E.
    Commented Jan 13, 2023 at 15:21
23

What worked for me : getting the picture link from the feed and replacing "_s.jpg" with "_n.jpg"

9
  • I had to resort to that, too, but it felt really dirty and fragile. Still looking for a better way.
    – JK Laiho
    Commented Aug 23, 2012 at 9:44
  • Nice, its working. I feel like n stands for normal, while I put b i got the bigger one. Commented Aug 10, 2013 at 9:49
  • I had to resort to this as well. It's a shame that Facebook doesn't provide for this obviously necessary functionality in it's API.
    – jokeefe
    Commented Dec 6, 2013 at 3:18
  • 7
    @user1105951 I tried CBroe's answer. That does not work anymore. It returns an OAuthException with the message "(#100) No node specified".
    – jokeefe
    Commented Jan 12, 2014 at 23:19
  • 1
    _o gives the original image, if you want a drop in solution, see my answer below. Commented Apr 6, 2014 at 17:53
16

OK, I found a better way. When you retrieve a feed with the graph API, any feed item with a type of photo will have a field called object_id, which is not there for plain status type items. Query the Graph API with that ID, e.g. https://graph.facebook.com/1234567890. Note that the object ID isn't an underscore-separated value like the main ID of that feed item is.

The result of the object_id query will be a new JSON dictionary, where you will have a source attribute containing a URL for an image that has so far been big enough for my needs.

There is additionally an images array that contains more image URLs for different sizes of the image, but the sizes there don't seem to be predictable, and don't all actually correspond to the physical dimensions of the image behind that URL.

I still wish there was a way to do this with a single Graph API call, but it doesn't look like there is one.

3
  • If the “album size version” is OK for you, then there is a simpler way – see my answer.
    – CBroe
    Commented Aug 28, 2012 at 13:20
  • you're right. This is the most standard way to do so. (less chance to break)
    – Raptor
    Commented Mar 26, 2013 at 9:01
  • Most safe way, but...performance loss. Especially when you like to display the feed / posts in a custom way on a website and have to do an extra Graph Api call for "every" post to get a link to the larger picture. Commented Feb 3, 2015 at 20:32
8

For high res image links from:

  • Link posts
  • Video posts
  • Photo posts

I use the following:

Note: The reason I give the _s -> _o hack precedence over the object_id/picture approach is because the object_id approach was not returning results for all images.

var picture = result.picture;
if (picture) {
    if (result.type === 'photo') {
        if (picture.indexOf('_s') !== -1) {
            console.log('CONVERTING');
            picture = picture.replace(/_s/, '_o');
        } else if (result.object_id) {
            picture = 'https://graph.facebook.com/' + result.object_id + '/picture?width=9999&height=9999';
        }
    } else {
        var qps = result.picture.split('&');
        for (var i = 0; i < qps.length; i++) {
            var qp = qps[i];
            var matches = qp.match(/(url=|src=)/gi);
            if (matches && matches.length > 0) picture = decodeURIComponent(qp.split(matches[0])[1]);
        }
    }
}
4
  • This works extremely well. You can build in a check for if a picture doesn't load from changing _s to _o or _n (easy using Picasso), to just get the object id and get the source from there via another api call.
    – Wenger
    Commented May 1, 2014 at 13:31
  • Good suggestion! I didn't really need that functionality but that would be a good idea for someone who really needed the largest image. Commented May 1, 2014 at 23:40
  • Since this still seems to be the best method I've seen, here's an update. Everything finishes with _n.jpg or _n.png now. No need to replace those. Instead you have to get rid of the /p130x130 or /s130x130.
    – Wenger
    Commented Aug 16, 2014 at 1:32
  • I think this method is outdated and no longer works. Facebook have secured their image URLs with a hash that cannot be manipulated.
    – Simon E.
    Commented Jan 13, 2023 at 15:23
6

This is a new method to get a big image. it was born after the previews method doesn't works

     /**
     * return a big url of facebook
     * works onky for type PHOTO
     * @param picture 
     * @param is a post type link
     * @return url of image
     */
    @Transactional
    public String getBigImageByFacebookPicture(String pictrue,Boolean link){
        if(link && pictrue.contains("url=http")){
            String url = pictrue.substring(pictrue.indexOf("url=") + 4);
            try {
                url = java.net.URLDecoder.decode(url, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                StringBuffer sb = new StringBuffer("Big image for Facebook link not found: ");
                sb.append(link);
                loggerTakePost.error(sb.toString());
                return null;
            }
            return url;
        }else{
            try {
                Document doc = Jsoup.connect(pictrue).get();
                return doc.select("#fbPhotoImage").get(0).attr("src");
            } catch (Exception e) {
                StringBuffer sb = new StringBuffer("Big image for Facebook link not found: ");
                sb.append(link);
                loggerTakePost.error(sb.toString());
                return null;
            }
        }
    }

Enjoy your large image :)

8
  • 1
    your answer solved the problem for me, I recommend it to everybody
    – TooCooL
    Commented Sep 23, 2014 at 23:01
  • 1
    I asked the question, and for now, it seems your answer is the best solution. great job. Commented Oct 11, 2014 at 10:00
  • for all that used this answer and want to remove the 130x130 no matter if it's 130x130 or s433x23 or p43x43 check this : stackoverflow.com/questions/26313382/… Commented Oct 11, 2014 at 10:47
  • 1
    Changing CDN urls are a bad idea
    – WizKid
    Commented Nov 17, 2014 at 6:23
  • Yes, i know, it has changed! Commented Feb 5, 2015 at 8:31
4

Actually, you need two different solutions to fully fix this.

1] https://graph.facebook.com/{object_id}/picture

This solution works fine for images and videos posted to Facebook, but sadly, it returns small images in case the original image file was not uploaded to Facebook directly. (When posting a link to another site on your page for example).

2] The Facebook Graph API provides a way to get the full images in the feed itself for those external links. If you add 'full_picture' to the fields like in this example below when calling the API, you will be provided a link to the higher resolution version.

https://graph.facebook.com/your_facebook_id/posts?fields=id,link,full_picture,description,name&access_token=123456

Combining these two solutions I ended up filtering the input in PHP as follows:

if ( isset( $post['object_id'] ) ){
    $image_url  =   'https://graph.facebook.com/'.$post['object_id'].'/picture';

}else if ( isset( $post['full_picture'] ) ) {
    $image_url  =   $post['full_picture'];

}else{
    $image_url  =   '';
}
6
  • 1
    Tried this, but...the full_picture link unfortunately points to a rather small image :( Commented Feb 3, 2015 at 20:51
  • Your right @YoupTube After some more experimentation I will need to update my answer... Commented Feb 4, 2015 at 10:39
  • 3
    From another post I learned to use "attachments". That one is working for me. It includes a Media node with Image and source. Try it yourself! Commented Feb 4, 2015 at 10:40
  • 1
    This is the best solution for the latest API here, but @YoupTube solution is better, you just need to do a little research for "attachments" attribute :) BenjaminKuijten I advice you to edit your post with attachments it will be great. Commented Feb 18, 2015 at 8:53
  • If you plan to edit take in mind that you should keep your logic and add the attachments case on top, because some times there are not attachments and the the only way left is the "/picture" solution. Commented Feb 18, 2015 at 9:31
1

See: http://api-portal.anypoint.mulesoft.com/facebook/api/facebook-graph-api/docs/reference/pictures

Just put "?type=large" after the URL to get the big picture.

1
  • I feel like this is probably the most viable solution here. Worth noting that /me/picture?type=large will 302 redirect to the image itself. If you want the actual data, including the image URL then you will need to pass the ?redirect=false parameter. Commented Sep 17, 2015 at 15:31
0

Thanks to @mattdlockyer for the JS solution. Here is a similar thing in PHP:

$posts = $facebook->api('/[page]/posts/', 'get');

foreach($posts['data'] as $post)
{
    if(stristr(@$post['picture'], '_s.'))
    {
        $post['picture'] = str_replace('_s.', '_n.', @$post['picture']);
    }

    if(stristr(@$post['picture'], 'url='))
    {
        parse_str($post['picture'], $picturearr);
        if($picturearr['url'])
            $post['picture'] = $picturearr['url'];
    }

    //do more stuff with $post and $post['picture'] ...
}
0

After positive comment from @Lachezar Todorov I decided to post my current approach (including paging and using Json.NET ;):

try
{
    FacebookClient fbClient = new FacebookClient(HttpContext.Current.Session[SessionFacebookAccessToken].ToString());

    JObject posts = JObject.Parse(fbClient.Get(String.Format("/{0}/posts?fields=message,picture,link,attachments", FacebookPageId)).ToString());
    JArray newsItems = (JArray)posts["data"];

    List<NewsItem> result = new List<NewsItem>();

    while (newsItems.Count > 0)
    {
        result.AddRange(GetItemsFromJsonData(newsItems));

        if (result.Count > MaxNewsItems)
        {
            result.RemoveRange(MaxNewsItems, result.Count - MaxNewsItems);
            break;
        }

        JToken paging = posts["paging"];

        if (paging != null)
        {
            if (paging["next"] != null)
            {
                posts = JObject.Parse(fbClient.Get(paging.Value<String>("next")).ToString());
                newsItems = (JArray)posts["data"];
            }
        }
    }

    return result;
}

And the helper method to retieve individual items:

private static IEnumerable<NewsItem> GetItemsFromJsonData(IEnumerable<JToken> items)
{
    List<NewsItem> newsItems = new List<NewsItem>();

    foreach (JToken item in items.Where(item => item["message"] != null))
    {
        NewsItem ni = new NewsItem
        {
            Message = item.Value<String>("message"),
            DateTimeCreation = item.Value<DateTime?>("created_time"),
            Link = item.Value<String>("link"),
            Thumbnail = item.Value<String>("picture"),

            // http://stackoverflow.com/questions/28319242/simplify-looking-up-nested-json-values-with-json-net/28359155#28359155
            Image = (String)item.SelectToken("attachments.data[0].media.image.src") ?? (String)item.SelectToken("attachments.data[0].subattachments.data[0].media.image.src")
        };
        newsItems.Add(ni);
    }

    return newsItems;

}

NewsItem class I use:

public class NewsItem
{
  public String Message { get; set; }
  public DateTime? DateTimeCreation { get; set; }
  public String Link { get; set; }
  public String Thumbnail { get; set; }
  public String Image { get; set; }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.