При загрузке фидов Facebook с одной страницы, если в канале есть изображение, я хочу отобразить большое изображение.
Как я могу получить с graph API
? Ссылка на изображение в фиде не является большой.
Спасибо.
При загрузке фидов Facebook с одной страницы, если в канале есть изображение, я хочу отобразить большое изображение.
Как я могу получить с graph API
? Ссылка на изображение в фиде не является большой.
Спасибо.
Это новый метод получения большого изображения. он появился после того, как метод предварительного просмотра не работает.
/**
* 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;
}
}
}
Наслаждайтесь большим изображением:)
Фотографический объект Graph API имеет соединение picture
(похожее на объект пользователя):
"Размер фотографии, размер которого зависит от альбома. [...] Возвраты: HTTP 302 перенаправляет URL-адрес изображения.
Таким образом, запрос https://graph.facebook.com/{object-id-from-feed}/picture
немедленно перенаправит вас на версию с размером альбома. (Полезно не только для отображения его в браузере, но и если вы хотите загрузить изображение на свой сервер, используйте параметр cURL with follow_redirect.)
Edit:
Начиная с API v2.3, край /picture
для сообщений фида устарел.
Однако в качестве поля изображение все еще можно запросить - но оно будет маленьким.
Но full_picture
также доступен.
So /{object-id-from-feed}?fields=picture,full_picture
может использоваться для запроса этих запросов, или их можно запросить напрямую с остальными данными фида, например, это /page-id/feed?fields=picture,full_picture,…
(дополнительные поля, такие как сообщение и т.д., должны быть указаны одинаково).
Что сработало для меня:
получая ссылку на изображение из фида и заменяя "_s.jpg
" на "_n.jpg
"
Хорошо, я нашел лучший способ. Когда вы загружаете фид с API-интерфейсом графика, любой элемент фида с типом photo
будет иметь поле с именем object_id
, которое не существует для простых элементов типа status
. Запросите API-интерфейс Graph с этим идентификатором, например. https://graph.facebook.com/1234567890
. Обратите внимание, что идентификатор объекта не является разделительным значком, отличным от основного идентификатора этого элемента фида.
Результатом запроса object_id
будет новый словарь JSON, в котором у вас будет атрибут source
, содержащий URL-адрес для изображения, которое до сих пор было достаточно большим для моих нужд.
Существует также массив images
, который содержит больше URL-адресов изображений для разных размеров изображения, но размеры там не кажутся предсказуемыми и не все действительно соответствуют физическим размерам изображения позади этот URL.
Я все еще хочу, чтобы был способ сделать это с помощью одного вызова Graph API, но не похоже, что он есть.
Для ссылок с высоким разрешением:
Я использую следующее:
Примечание.. Причина, по которой я выделяю _s -> _o
приоритет взлома над подходом object_id/picture
, заключается в том, что метод object_id не возвращал результаты для всех изображений.
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]);
}
}
}
На самом деле вам нужно два разных решения, чтобы полностью исправить это.
1] https://graph.facebook.com/ {object_id}/picture
Это решение отлично подходит для изображений и видеороликов, размещенных в Facebook, но, к сожалению, оно возвращает небольшие изображения, если исходный файл изображения не был загружен прямо на Facebook. (Например, при отправке ссылки на другой сайт на вашей странице).
2] API-интерфейс Facebook предоставляет возможность получить полные изображения в самой канале для этих внешних ссылок. Если вы добавите "full_picture" в поля, как в этом примере ниже, при вызове API, вам будет предоставлена ссылка на версию с более высоким разрешением.
Объединив эти два решения, я включил фильтрацию ввода в PHP следующим образом:
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 = '';
}
Смотрите: http://api-portal.anypoint.mulesoft.com/facebook/api/facebook-graph-api/docs/reference/pictures
Просто поместите "? type = large" после URL, чтобы получить большую картинку.
Благодаря @mattdlockyer для решения JS. Вот аналогичная вещь в 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'] ...
}
После положительного комментария от @Lachezar Todorov я решил опубликовать свой текущий подход (, включая пейджинг и используя 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;
}
И вспомогательный метод для удаления отдельных элементов:
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/info/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, который я использую:
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; }
}