iPhone OS: стратегии работы с изображениями высокой плотности

У меня есть проект, который приближается к концу этим летом, который потенциально будет включать в себя чрезвычайно большой объем данных изображения для отображения. Мы говорим о сотнях изображений размером 640x480 пикселей в данном сеансе приложения (с уменьшенным разрешением при отображении) и о нескольких очень больших (1280x1024 или выше) изображениях одновременно.

Я уже проделал некоторую предварительную работу и обнаружил, что типичное изображение 640x480ish - это просто тень менее 1 МБ в памяти при помещении в UIImageView и отображении ... но очень большие изображения могут быть колоссальными 5+ МБ в некоторых случаи.

Этот проект на самом деле нацелен на iPad, который, согласно моим тестам Instruments, ограничен примерно 80-100 МБ адресуемой физической памяти.

Помимо деталей, мне нужно начать думать о том, как перемещать огромные объемы данных изображений между виртуальной и физической памятью, сохраняя при этом плавность и скорость отклика приложения, что обеспечит высокую видимость.

Я, вероятно, нахожусь на более высоком уровне среднего в Objective-C ... поэтому я ищу несколько серьезных статей и советов по следующему:

1) Ответственное управление UIImage и UIImageView во имя сохранения физической RAM 2) Достоинства использования CGImage вместо UIImage, особенно для огромных изображений, и если будет какой-либо прирост производительности 3) Все, что связано с разбиением на страницы памяти, особенно в том, что касается картинки

В качестве эпилога я скажу, что приведенные выше цифры могут отличаться примерно на 10-15%. Изображения могут или не могут в конечном итоге объединяться в само приложение, а не загружаться с внешнего сервера.


person M. Ryan    schedule 20.04.2010    source источник


Ответы (3)


CATiledLayer, вероятно, лучший вариант. Единственная причина для создания UIImageView для каждого изображения - если вам нужна управляемая интерактивность. CATiledLayer позволит вам асинхронно загружать и рисовать изображения из фоновых потоков по мере необходимости. Просто используйте CGImage, так как это то, что вы все равно будете рисовать на слое.

Вы, вероятно, захотите реализовать свой собственный кэш потоковых изображений, чтобы вы могли наложить ограничение на количество изображений, хранящихся в памяти, и начать загрузку изображений, когда вы предсказываете, что они скоро понадобятся. Если загрузка не завершена, когда поступает запрос на отрисовку, вы можете заблокировать поток отрисовки.

person drawnonward    schedule 01.05.2010

Изображения обычно содержат много повторяющихся данных и хорошо подходят для сжатия. это зависит от того, какой формат вы используете для своих изображений и имеет ли он встроенное сжатие. Моя первая мысль - придерживаться формата png, потому что он родной для iPhone, и каким-то образом использовать архив сжатия для большей части ваших изображений. Что-то вроде .zip или .rar.

если вы можете определить пакеты изображений, с которыми может столкнуться пользователь, вы можете затем разархивировать их и предоставить пользователю. Также может оказаться полезным использование подмножества архива «эскизов».

Я не уверен, что все это сжатие и распаковка повлияет на время отклика, но это идея уменьшить объем памяти.

person Ed Wist    schedule 21.04.2010
comment
Знаете ли вы, что PNG как собственный формат приведет к уменьшению занимаемой площади по сравнению с размером на диске? Все изображения, о которых идет речь, в настоящее время являются изображениями в формате JPEG из-за архитектурных требований. их источника, однако я могу написать пакетное задание для их преобразования. Я мог поверить в сценарий, когда JPEG, который не поддерживается должным образом, может потреблять больше памяти, чем PNG, при условии, что у Apple есть некоторые сложные методы обработки PNG. - person M. Ryan; 21.04.2010
comment
Я бы придерживался JPG, они более сжимаются по сети для большинства изображений, и нет никаких доказательств того, что они более эффективны для рендеринга. Пища для размышлений: stackoverflow.com/questions/800926/ - person Brian King; 28.04.2010
comment
Если вы уже в формате JPG, думаю, у вас все в порядке. Я согласен с вышеизложенным. - person Ed Wist; 28.04.2010

Это довольно сложный вопрос, поэтому я покажу вам проект, представляющий собой карту с открытым исходным кодом. Вы можете повторно использовать этот проект оптом, добавив свой сервер в качестве источника данных (если он основан на lng / lat, что может иметь смысл), или вы можете взять некоторые шаблоны проектирования и напрямую реализовать свои требования.

http://code.google.com/p/route-me/source/browse/trunk#trunk/MapView/Map

Тот факт, что ваши изображения имеют размер 1 или 5 МБ, не является проблемой, так как вы должны отображать только 1 или 4 изображения одновременно. Затем асинхронный загрузчик кеша, который наполняет и выдерживает ваш кеш изображений в зависимости от того, что пользователь может посмотреть дальше. Затем, когда пользователь взаимодействует, возьмите изображение из кеша (или счетчик при промахе кеша), добавьте его в CALayer и вставьте в иерархию CALayer.

Есть много вопросов о производительности / использовании. Я свяжусь с кем-нибудь из вышеупомянутого проекта или просто последую его примеру. На основе того, что я знаю о проекте, это означает один UIView для родительского контейнера, который передает события, и использование CALayers для всей мозаики. CGImageRefs используются в CALayers, так что придерживайтесь и их.

Надеюсь это поможет.

person Brian King    schedule 28.04.2010