Изменение размера изображений на Windows Phone 7 в потоке пула потоков?
Я пишу приложение Windows Phone 7, которое имеет дело с большим количеством изображений. Эти изображения могут варьироваться от нескольких сотен пикселей до 1080P (потенциально выше в будущем).
Изображения очень ресурсоемкие, поэтому я пошел по пути кэширования + изменения размера изображений на телефоне перед их отображением.
Это означает, что при первой настройке после ввода пользователем IP-адреса хранилища изображений я могу попросить их подождать несколько минут, пока все они будут восстановлены/изменены/кэшированы. С этого момента они могут иметь приятную и быструю работу.
В настоящий момент менеджер кэша отслеживает изображения через словарь Uri и расположение файлов. У меня есть очередь, которая обрабатывает до 5 изображений за один раз (веб-запросы Async, изменение размера выполняется в потоке пула потоков).
Проблема заключается в том, что класс WritableBitmap в Silverlight является элементом пользовательского интерфейса, то есть я должен перейти к потоку пользовательского интерфейса через диспетчер, чтобы сделать фактическое изменение размера, которое является глупым и замедляет все это. Это также означает, что мой Cache Manager эффективно однопоточный.
Таким образом, он запускает диспетчер кэша (пул потоков) → веб-запрос Async (пул потоков) → обратный вызов (пул потоков) → изменение размера (поток пользовательского интерфейса) → завершение задания кэширования (пул потоков).
Я искал стороннюю библиотеку, которая будет A) Компилировать и запускать на Windows Phone 7 и B) Можете изменять размеры изображений различных форматов, манипулируя потоком или массивом байтов и не завися от потока пользовательского интерфейса.
У кого-нибудь есть опыт?
Приветствия,
Тайлер
Ответы
Ответ 1
Чтобы уменьшить размер загружаемого файла и, чтобы удалить нагрузку на обработку с центрального процессора телефона, я бы нажал эту работу на веб-службу.
Например, вы можете разместить такую службу, как код WebImageResizer с открытым исходным кодом, где-то в Интернете http://webimageresizer.codeplex.com/ - например. на бесплатном сервере AppHarbor.
Или вы можете использовать коммерческую услугу (freemium), например:
Любой из них позволит вам быстро обрабатывать изображения на сервере с помощью сверхбыстрого соединения и juse доставлять меньшие изображения на телефон с ограниченным подключением к данным.
Ответ 2
Библиотека ImageTools поддерживает WP7 и поддерживает изменение размера изображения, поэтому у вас может быть больше успеха с помощью этого.
Ответ 3
Попробуйте http://writeablebitmapex.codeplex.com/, созданный Рене Шульте. Он имеет лучшую производительность как WriteableBitmap, поставляемый с SDK.
Ответ 4
Являются ли файлы, которые вы хотите отобразить на своем сервере?
Если да, на мой взгляд, вы выбрали неправильный подход к этой проблеме. Бессмысленно передавать тяжелые изображения, а затем изменять их размер. Я рекомендую хранить их на низком и высоком разрешении на сервере.
Если нет, я не могу вам помочь. Я нашел эту статью, но я думаю, что вы уже видели это.
Ответ 5
Tyler - Вы упомянули, что при первом запуске приложение извлекает изображения с IP-адреса (в Интернете, я полагаю)?
Это означает, что при первой настройке после ввода пользователем IP-адреса хранилища изображений я могу попросить их подождать несколько минут, пока все они будут восстановлены/изменены/кэшированы. С этого момента они могут иметь приятную и быструю работу.
Если это правильно, то, что я думаю, некоторые из предложенных ответов в создании прокси-сервера - фактически возможное решение. Я бы структурировал это следующим образом:
Ваше приложение → Веб-запрос для обработчика прокси-сервера
string imageUrl = HttpUtility.UrlEncode("http://[user's_ip]/path_to_image.png");
http://domain.com/your_proxy.ashx?users_image_url=imageUrl
Прокси-обработчик на задней панели должен запросить изображение, изменить его размер и вернуть измененное изображение обратно в ваше приложение.
Ваше приложение → Кэш возвращенного измененного изображения
Петля по мере необходимости...
ОБНОВЛЕНО:
Оказывается, есть способ изменить размер изображений на WP7 за пределами потока пользовательского интерфейса, используя собственный класс WriteableBitmap. Существует метод под названием .SaveJpeg(), который позволяет это, и мы используем его в настоящее время в нашем приложении WP7 CitySourced. Ваш код должен выглядеть примерно так:
wb.SaveJpeg(stream, width, height, orientation, quality);
Единственным обломком является то, что он работает только при записи файла .JPG, и нет поддержки .PNG. Сообщите мне, работает ли это для вашего случая использования.
Ответ 6
Я не думаю, что ваша проблема - это производительность, но как вы собираетесь показывать изображения. Я думаю, что было бы лучше всегда показывать миниатюру по умолчанию, а затем обновлять миниатюру, если она была изменена вашим фоном. Приложение должно быть использовано гораздо быстрее.
Ответ 7
http://www.dtksoft.com/dtkimage.php
Это работает со всеми форматами файлов и совместим с Windows Mobile