Работаем с Flickr на .NET Compact Framework

Что-то все больше меня уносит в сторону ПО, работающего со всякими online-сервисами. Вон было недавно о Google Translate и Yahoo! Maps, а сегодня буду рассказывать о том как работать с сервисом хостинга фотографий Flickr на .NET Compact Framework.
Итак, предметом нашего внимания сегодня будет библиотека Flickr.NET, которую можно найти на CodePlex. Flickr.NET – это библиотека с открытым исходным кодом, есть версия для .NET Compact Framework. Вот ее мы и будем использовать.
Для начала Создаем новый проект для Smart Device на C#.
Затем распаковываем исходный код Flickr.NET в папку с созданным решением (рядом с папкой, в которой находится исходный код только что созданного проекта).
После этого добавляем проект FlickrNetCF в решение
Добавляем ссылку на проект FlickrNetCF в список зависимостей нашего приложения (с помощью Project -> Add Reference).
Ну вот, теперь можно работать.
Рисуем вот такую форму:
На форме:
- Поле ввода запроса для поиска изображений
- Кнопка поиска
- Список (ListView) для просмотра информации о найденных изображениях
- Кнопка открытия формы для просмотра полноразмерного изображения
Теперь можно заняться, собсьвенно, работой с Flickr. Для работы с сервисом в библиотеке FlickrNetCF есть класс Flickr. Для работы ему необходимы:
- Application Key
- Secret Key
Получить эти два ключа можно вот по этому адресу.
Создаем объект для работы с сервисом
using FlickrNet; ... Flickr _flickr = new Flickr(); _flickr.ApiKey = "<здесь будет ваш API Key>"; _flickr.ApiSecret = "<здесь будет ваш Secret Key>";
Теперь нам неплохо бы обеспечить поиск изображений и отображение превью, а также информации об изображении. Загрузка превью – процесс длительный, поэтому обрабатывать информацию, полученную от сервиса будем в отдельном потоке:
Thread _downloadThread; string _searchText = ""; ... private void StartDownloadingPreviws() { if (_downloadThread != null) { _downloadThread.Abort(); } photoInfoListView.Items.Clear(); photoThumbnailList.Images.Clear(); _searchText = searchTextBox.Text; _downloadThread = new Thread(new ThreadStart(DownloadPhotosDelegate)); _downloadThread.Start(); }
Для поиска изображений в классе Flickr предусмотрен метод PhotosSearchText()
, который в качестве параметра принимает строку поискового запроса. Именно этот метод мы и будем использовать для получения информации о найденных фотографиях. Метод PhotosSearchText()
возвращает объект класса Photos
, из которого мы можем получить всю информацию о найденных изображениях (свойство PhotoCollection
класса Photos
возвращает массив объектов Photo
, каждый из которых содержит полную информацию об одном изображении, например, название, ссылку на превью, ссылку на полноразмерное изображение и др.)
void DownloadPhotosDelegate() { try { Photos _photos = _flickr.PhotosSearchText(_searchText); foreach (Photo photo in _photos.PhotoCollection) { MemoryStream photoStream = new MemoryStream(); WebRequest request = HttpWebRequest.Create(photo.SquareThumbnailUrl); WebResponse response = request.GetResponse(); MemoryStream stream = new MemoryStream(); Stream responseStream = response.GetResponseStream(); int readCount = 0; byte[] buffer = new byte[1024]; while ((readCount = responseStream.Read(buffer, 0, buffer.Length)) > 0) { stream.Write(buffer, 0, readCount); } response.Close(); Bitmap bmp = new Bitmap(stream); string originalURL = photo.LargeUrl; string title = photo.Title; Invoke(new AddItemDelegate(AddItemToList), new object[] { bmp, title, originalURL}) } } catch (ThreadAbortException) { } catch (Exception ex) { MessageBox.Show(ex.Message); } }
Т.к. в .NET неглавный поток не может работать с элементами GUI, то добавление превью изображений в список нам необходимо делать в отдельном методе, который будет вызываться посредством Invoke():
Invoke(new AddItemDelegate(AddItemToList), new object[] { bmp, title, originalURL}); ... private delegate void AddItemDelegate(Bitmap bmp, string name, string originalURL); Bitmap ResizeBitmap(Bitmap b, System.Drawing.Size size) { Bitmap result = new Bitmap(size.Width, size.Height); using (Graphics g = Graphics.FromImage((Image)result)) g.DrawImage(b, new Rectangle(0, 0, result.Width, result.Height), new Rectangle(0, 0, b.Width, b.Height), GraphicsUnit.Pixel); return result; } void AddItemToList(Bitmap bmp, string name, string originalURL) { try { photoThumbnailList.Images.Add(bmp); ListViewItem newItem = new ListViewItem(name); newItem.ImageIndex = photoThumbnailList.Images.Count - 1; newItem.Tag = originalURL; photoInfoListView.Items.Add(newItem); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
ОК, с главной формой пока закончили. теперь приступим к созданию формы для просмотра полноразмерного изображения.
Добавляем в проект новую форму. На нее кладем Panel (Dock = Fill, AutoScroll = true), на Panel кладем PictureBox.
Теперь нам нужно обеспечить загрузку изображения в отдельном потоке. Подход приблизительно такой же как и в главной форме:
private Thread _downloader; private string _imageURL = ""; Bitmap _sourceBitmap; public string ImageURL { get { return _imageURL; } set { _imageURL = value; } } public ImageViewForm() { InitializeComponent(); } void OnImageDownloaded(Bitmap bmp) { _sourceBitmap = bmp; imageBox.Image = bmp; imageBox.Width = bmp.Width; imageBox.Height = bmp.Height; } private delegate void ImageDownloadedDelegate(Bitmap bmp); void DownloadImage() { try { do { if (ImageURL == null || ImageURL.Length == 0) break; WebRequest request = HttpWebRequest.Create(ImageURL); WebResponse response = request.GetResponse(); Bitmap bmp = new Bitmap(response.GetResponseStream()); response.Close(); Invoke(new ImageDownloadedDelegate(OnImageDownloaded), new object[] { bmp }); } while (false); } catch (ThreadAbortException) { } catch (Exception ex) { MessageBox.Show(ex.Message); } } public void StartDownloading() { _downloader = new Thread(new ThreadStart(DownloadImage)); _downloader.Start(); } private void ImageViewForm_Closing(object sender, CancelEventArgs e) { if (_downloader != null) { _downloader.Abort(); } }
Теперь пишем обработчик нажатия кнопки открытия формы просмотра полноразмерного изображения в главной форме
private void showPictureButton_Click(object sender, EventArgs e) { do { if (photoInfoListView.SelectedIndices.Count == 0) break; ListViewItem item = photoInfoListView.Items[photoInfoListView.SelectedIndices[0]]; if (item == null) break; string url = (item.Tag as string); if (url == null || url.Length == 0) break; ImageViewForm dlg = new ImageViewForm(); dlg.ImageURL = url; dlg.StartDownloading(); dlg.ShowDialog(); } while (false); }
Ну вот, собственно и все. В результате мы получим вот такое приложение:
Исходный код тестового приложения, а также исполняемый файл можно скачать здесь.
Еще интересные посты о программировании для мобильных устройств:
No Comments
Make A CommentNo comments yet.
Comments RSS Feed TrackBack URL