2013-05-02 4 views
4

У меня очень большая карта привет-Res, которую я хочу использовать в приложении (размер изображения составляет около 80 мб).Масштабирование и загрузка очень большого файла TIFF

Я хотел бы знать следующее:

  • Как я могу загрузить это изображение как можно лучше? Я знаю, что загрузка изображения займет примерно несколько секунд (это нормально), но я хотел бы уведомить пользователя о прогрессе. Я хотел бы использовать определенный режим и показывать это в виде JProgressBar пользователю. Это должно отражать количество загруженных байтов или что-то в этом роде. Есть ли способ загрузки изображений, который может обеспечить эту функцию (например, ImageIO.read())?
  • Поскольку карта имеет очень высокое разрешение, я хотел бы предложить пользователю прокрутить, чтобы увеличивать и уменьшать масштаб. Как я могу сделать это наилучшим образом? Я знаю, что для масштабирования BufferedImage стандартный способ займет очень большой срок для такого большого файла. Есть ли эффективный способ сделать это?

Благодарим за внимание!

Уважением,
Эктор ван ден Boorn

P.S. Изображение будет нарисовано на холсте JPanel.


Привет, Андрей, Большое вам спасибо за вашу помощь; все отлично работает и быстро загружается. Без вашего опыта и объяснений я бы все еще работал над этим, чтобы вы заслужили награду и площадь.

Я сделал следующее: используя imagemagick, я создал несколько изображений разного разрешения и в начале выполнения загрузил только самые маленькие res. образ. Остальные загружаются в отдельные потоки, поэтому выполнение не останавливается. Используя предоставленную вами информацию, я затем использую соответствующие изображения при масштабировании или выходе. Я немного скептически отношусь к использованию плиток, потому что мне нужно нарисовать собственные изображения поверх карты, и я не мог найти функцию краски во внешней банке, которую вы мне сказали, поэтому я в итоге использовал что-то простое; когда масштабирование или панорамирование режима масштабирования установлено на быстрый, и когда вы не масштабируете или панорамируете, масштаб масштабирования настроен на сглаживание для изображений, идеально подходящих для пикселя (как и вы предполагали), но это оказывается достаточно быстрым, и я не уверен, Мне нужны плитки (хотя я вижу, что с более крупными изображениями это было бы необходимо, и я понимаю информацию, которую вы мне дали).

Так что спасибо еще раз и все работает отлично :)

+0

Возможно, это вариант для отслеживания прямоугольника, который нужно отобразить и выбрать часть изображения для зрителя? Как это работает с панорамированием изображения (перемещение изображения, например, влево)? –

ответ

2

Есть два подхода вы должны (одновременно) принять:

  1. Спустившихся изображения в различные размеры. Вы должны уменьшить масштаб изображения с помощью ряда более низких разрешений (1/2, 1/4, 1/8 и т. Д., Пока изображение не будет отображаться с наибольшим вероятным разрешением экрана). Когда пользователь сначала открывает изображение, вы показываете изображение с более низким разрешением. Это быстро загрузится и позволит пользователю панорамироваться. Когда пользователь увеличивает масштаб изображения, вы используете изображение с более высоким разрешением. Вы можете использовать ImageMagick для этого: http://www.imagemagick.org/Usage/resize/
  2. Tile Ваши большие изображения. Это разбивает одно крупное изображение на большое количество небольших изображений в виде сетки. Когда пользователь масштабируется в области, вы вычисляете, какие плитки пользователь ищет, и вы визуализируете только их, а не другие области изображения.Вы можете использовать ImageMagick для разделения изображения на плитку, например ImageMagick. What is the correct way to dice an image into sub-tiles. Документация http://www.imagemagick.org/Usage/crop/#crop_tile

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

После у вас есть ваши плитки, вы можете использовать один из нескольких двигателей в Java:

Могут быть и другие.

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

  1. Для уровня масштабирования, выбранного пользователем, выбрать ближайший кэш разрешения выше. Например, если у вас есть 100%, 50%, 25% и 12,5% плитки, и пользователь выбирает 33% масштабирования, выберите 50% плитки
  2. Установите макет для плиток, чтобы квадраты плитки имели правильный размер для выбранный масштаб (это может быть одиночная плитка при самых низких уровнях масштабирования). Например, при 33% масштабировании с использованием 50% плиток, при этом плитки равны 100 пикселям, сетка будет составлять 67 пиксельных квадратов.
  3. Индивидуально загружать и масштабировать изображения плитки в соответствии с экраном (это может быть многопоточное, что работает а на современных архитектур процессоров)

есть несколько моментов, чтобы отметить:

  1. The scaling algorithm изменения, когда вы достигнете наибольшего разрешения у вас есть плитка для.
    1. До 100% масштабирования изображения, используйте билинейное или бикубическое масштабирование. Это обеспечивает отличные внешний вид для фотографий с небольшой зубчатостью
    2. выше 100%, вы, вероятно, хотите, чтобы показать пиксели, поэтому ближайший сосед может быть хорошим выбором
  2. Для более высокой точности, используйте более высокий масштаб плитку и уменьшение масштаб > 50%. Например, предположим, что у вас есть плитка, приготовленная на 100%, 50%, 25% и 12,5%. Чтобы показать 40% масштабирование, не уменьшайте 50% плитки; вместо этого используйте 100% плитки и уменьшите их до 40%. Это полезно:
    1. Если ваши изображения являются текстовыми или диаграммами (то есть растровыми изображениями, содержащими много прямых линий). Масштабирование эти типы изображений часто производят неприятные артефакты, если вы не передискретизации
    2. Если вам нужна очень высокая точность на изображениях фотографического типа
  3. Если вам нужно сделать предварительный просмотр масштабирования (например, в то время как пользователь по-прежнему сжимает и масштабирует), возьмите снимок экрана в начале жестов и увеличьте масштаб. Это гораздо важнее, чем анимация гладкая, чем предварительный просмотр зума.
  4. Важным является выбор правильного размера плитки.Очень большие плитки (< 1 на экран) медленно визуализируются. Слишком маленькие плитки создают другие накладные расходы и часто создают неприятные артефакты рендеринга, где вы видите случайное заполнение экрана. Хороший компромисс между производительностью и сложностью заключается в том, чтобы сделать плитки примерно на четверть полноэкранного размера.

При использовании этих методов, изображения должны загрузить гораздо быстрее, и поэтому прогресс бар не столь важно. Если это так, то вам необходимо зарегистрировать IIOReadProgressListener на ImageReader:

От JavaDoc:

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

Этот интерфейс получает общее представление о ходе декодирования (с помощью методов imageProgress и thumbnailProgress) и события, указывающие, когда было обновлено целое изображение (с помощью методов imageStarted, imageComplete, thumbnailStarted и thumbnailComplete). Приложения, которые хотят получать информацию о обновлениях пикселей по мере их возникновения (например, при прогрессивном декодировании), должны предоставить идентификатор IIOReadUpdateListener.

+0

Привет, спасибо за ваш ответ. Если я правильно понял, у меня было бы для каждого уровня масштабирования другая карта (разного разрешения), и каждая из этих карт должна была бы быть разбита? Поэтому для самой масштабированной карты у меня будет, например, 1 плитка, содержащая все и для самой масштабированной карты, которую я бы имел, например. 100 плиток? –

+0

@ HéctorvandenBoorn: Вы в основном правы, но есть подходы к реализации произвольного масштабирования - я добавил больше подробностей в свой ответ о том, как реализовать это. Отличный способ увидеть это в действии - Google Earth. Это также способ реализации мобильных браузеров (как iPhone, так и Android). Если вы работаете с браузером на большой странице, вы можете увидеть большие квадратные промежутки на мгновение, прежде чем браузер отобразит эту область. –

+0

Привет, Андрей, Большое вам спасибо за вашу помощь; все отлично работает и быстро загружается. –

Смежные вопросы