Просмотр больших изображений на странице в интернете


Предыдущие статьи были посвящены разным аспектам получения гигантских изображений из нескольких снимков. Теперь настало время разобраться с обратной задачей: как комфортно детально изучить фрагмент фотографии, не загружая ее целиком в компьютер. Очевидно, что для этого нужно разбить фотографию на фрагменты и иметь куски с разным разрешением. Эта идея получила название пирамиды из снимков. В основании этой пирамиды лежит разбитое на куски изображение с полным разрешением. Следующий уровень представляет собой тоже разбитое на куски, но уже меньшее изображение. И так вплоть до вершины, на которой лежит миниатюра, вмещающая всё изображение.

фото

Вероятно, наиболее часто необходимость детально рассматривать только часть изображения возникает при работе с географическими картами и результатами аэрофотосъемки. Поэтому неудивительно, что наиболее известные решения были предложены именно в рамках геоинформационных систем. Это формат GMAP, предложенный Google для своей картографической системы, формат TMS (Tile Map Service), предложенный в рамках развития картографического стандарта Open Source Geospatial Foundation, формат OZF2 в OziExplorer. Не осталась в стороне и компания Microsoft, разработавшая для просмотра больших изображений вообще и своего картографического проекта Deep Earth в частности свой собственный формат DZI (Deep Zoom image). Кроме того, собственные форматы были предложены в рамках проектов, непосредственно не связанных с картографией, например — Zoomify.

Microsoft сделала свой формат открытым, и в данной статье я рассматриваю средства работы с ним, разработанные в рамках проекта Open Zoom. Для разбиения изображений в формате Deep Zoom я использовал программу Python Deep Zoom ;Tools.

bash-4.1$ img2dzi
    Usage: img2dzi [options] filename
Options:
      -h, --help            show this help message and exit
      -d DESTINATION, --destination=DESTINATION
      Set the destination of the output.
      -s TILE_SIZE, --tile_size=TILE_SIZE
      Size of the tiles. Default: 254
      -f TILE_FORMAT, --tile_format=TILE_FORMAT
      Image format of the tiles (jpg or png). Default: jpg
      -o TILE_OVERLAP, --tile_overlap=TILE_OVERLAP
      Overlap of the tiles in pixels (0-10). Default: 1
      -q IMAGE_QUALITY, --image_quality=IMAGE_QUALITY
      Quality of the image output (0-1). Default: 0.8
      -r RESIZE_FILTER, --resize_filter=RESIZE_FILTER
      Type of filter for resizing (bicubic, nearest,
      bilinear, antialias (best). Default: antialias

Если программы img2dzi в вашем пакете не окажется, то можно запустить разбиение, отредактировав файл helloworld.py в папке deepzoom.py / examples /.

А для разбиения в форматы TMS, Zoomify и GMAP — программу MagickTiler. Это написанная на языке Java утилита для преобразования изображений, которая использует для манипуляции с фотографиями пакет программ GraphicsMagick.

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

фото
фото
4/0/1.jpg
(TMS)
3_0_4.jpg
(GMAP)
фото
фото
12/0_2.jpg
(DZI)
TileGroup0/4-0-2.jpg
( Zoomify)

И поэтому для того, чтобы просмотреть полученные фрагменты, в каждом случае нужна своя программа. Вероятно, самый простой вариант для пользователя — это воспользоваться программой MagickTiler для разбиения в tms с ключом -p.

bash-4.1$ java -jar magicktiler.jar -h
MagickTiler Version 0.9
      Copyright (C) 2010 AIT Austrian Institute of Technology.
      Additional licences apply to this software.
      See http://code.google.com/p/magicktiler for details.
usage: java -jar magicktiler [-b <color>] [-f <format>] [-g] [-h] -i
   <input> [-l] [-o <output>] [-p] [-q <quality>] -s <scheme> [-v]
      -b <color>     background color, default=white
      -f <format>    tile format ('jpeg' or 'png'), default=jpeg
      -g             displays the GUI (ignores all other parameters)
      -h             displays this help text
      -i <input>     mandatory input file or directory
      -l             writes reporting information to a log file
      -o <output>    output directory (for tilesets) or file (for PTIF),
      default=.
      -p             generate an HTML preview file
      -q <quality>   JPEG compression quality (0 - 100), default=75
      -s <scheme>    mandatory tiling scheme ('tms', 'zoomify', 'gmap' or
      'ptif')
      -v             validate the input instead of generating a tileset
      Example: java -jar magicktiler.jar -s tms -f jpeg -i image.tif -p

В этом случае программа, кроме разбиения, сразу формирует и пример html-файла с программой на JavaScript для его просмотра.

<!DOCTYPE html>
<html> <head> <title>tms - generated by MagickTiler</title> <script src="http://openlayers.org/api/OpenLayers.js" type="text/javascript"></script> <script type="text/javascript"> function init(){ var options = { controls: [], maxExtent: new OpenLayers.Bounds(0, 0, 10912, 4552), maxResolution: 64, numZoomLevels: 7, units: "pixels" }; var map = new OpenLayers.Map('map', options); var layer = new OpenLayers.Layer.TMS( "TMS Layer", "OpenLayers/", { layername: ".", serviceVersion: ".", transitionEffect: "resize", type:"jpg" } ); map.addLayer(layer); map.zoomToMaxExtent(); map.addControl(new OpenLayers.Control.PanZoomBar()); map.addControl(new OpenLayers.Control.MousePosition()); map.addControl(new OpenLayers.Control.MouseDefaults()); map.addControl(new OpenLayers.Control.KeyboardDefaults()); } </script> <style> html, body, #map { width:100%; height:100%; padding:0px; margin:0px; } </style> </head> <body onload="init()"> <div id="map"></div> </body>
</html>

Скрипт  OpenLayers.js довольно большой: около 722 КБ. В данном примере он загружается из интернета с сайта openlayers.org, но его можно скачать и расположить на локальной машине или своем сервере. Но, конечно, при просмотре огромных фотографий загрузка дополнительно и данного скрипта — это уже копейки. Пример просмотра фотографии в ИК-диапазоне, реализованный этим методом.

Примерно аналогичные возможности Magicktiler представляет и для формата GMAP. В результате получаем следующий html-файл:

<!DOCTYPE html>
<html> <head> <title>gmap - generated by MagickTiler</title> <script src="http://maps.google.com/maps?file=api&amp;v=2" type="text/javascript"></script> <script type="text/javascript"> function init() { if (GBrowserIsCompatible()) { var tilelayer = new GTileLayer(); tilelayer.getTileUrl = function(p,z) { return "gmap/"+z+"_"+p.x+"_"+p.y+".jpg"; }; tilelayer.getOpacity = function() { return 1.0;} var tilelayers = [tilelayer]; var mapType = new GMapType(tilelayers, new GMercatorProjection(6), "magicktiler"); mapType.getMinimumResolution = function() {return 0;} mapType.getMaximumResolution = function() {return 5;}
 var map = new GMap(document.getElementById("map"));
      map.addMapType(mapType);
      map.setCenter(new GLatLng(0, 0), 0, mapType);
      map.addControl(new GLargeMapControl());
      }
      }
   </script>
   <style>
      html, body, #map {
      width:100%;
      height:100%;
      padding:0px;
      margin:0px;
      }
   </style>
   </head>
   
   <body onload="init()">
   <div id="map"></div>
   </body>
</html>

Мне этот вариант понравился чуть меньше, да и на использование формата GMAP накладывает больше ограничений, чем наложено для формата TMS. Загружается целая серия скриптов из сети, суммарный объем которых, если и меньше, чем в предыдущем случае, то не на много. Использовать этот метод для просмотра на машине, не подключенной к интернету, весьма проблематично. Для размещения на веб-сайте требуется зарегистрировать ключ API Карт Google. JavaScript API Version 2 является официально устаревшим с 19 мая 2010 г.

Для себя я счел наиболее интересным вариант с форматом dzi. Во-первых, потому что он используется в программе просмотра панорам SaladoPlayer, и, на мой взгляд, пока еще просмотр с помощью технологии flash представляет наибольший комфорт. Для просмотра снимка, разбитого в этом формате, используется flash-проигрыватель и одна или две программы на JS, к которым обращаемся из html-файла. Файл проигрывателя OpenZoomViewer.swf можно собрать из исходных кодов. Для этого нам придется предварительно скачать и установить Adobe Open Source Flex ;SDK, OpenZoom SDK и исходный код программы просмотра Nano, базирующейся на OpenZoom SDK. После этого собираем SWF-файл командой:

bash-4.1$ mxmlc nano/src/OpenZoomViewer.as -output OpenZoomViewer.swf 
          -use-network=false -compiler.library-path lib nano/assets 
          -compiler.source-path src   

Естественно, подкорректировав пути в соответствии с вашим расположением файлов на диске. А можно воспользоваться и уже скомпилированным кем-то другим готовым файлом SWF. В этом случае текст, который надо вставить в html, будет выглядеть так:

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
 <script type="text/javascript" src="swfobject.js"></script>
 <script type="text/javascript">
 var flashvars = {};
 flashvars.source = "nano/01a.dzi"
 var params = {};
 params.play = "true";
 params.loop = "false";
 params.menu = "false";
 params.quality = "high";
 params.scale = "showall";
 params.wmode = "window";
 params.bgcolor = "#FFFFFF";
 params.devicefont = "false";
 params.allowfullscreen = "true";
 params.allowscriptaccess = "sameDomain";
 var attributes = {};
 swfobject.embedSWF("OpenZoomViewer.swf", "OpenZoom1", "580", "250", "10.0.0", 
 "expressInstall.swf", flashvars, params, attributes);
 </script>
 </head>
 <body>
 <div id="OpenZoom1">
   <a href="http://www.adobe.com/go/getflashplayer">
   <img src="/plugins/openzoom/get_flash_player.gif" alt="Get Adobe Flash player" />
   </a>
   </div>
   </body>
</html>

Это вариант в стиле SaladoPlayer, для которого требуется скрипт swfobject.js, входящий в его архив. Его и скомпилированный мной OpenZoomViewer.swf можно скачать здесь. Для корректной работы файл OpenZoomViewer.swf должен быть в той же папке, что и html-файл.

Можно воспользоваться и чуть другим вариантом из примера в более старом, чем nano, варианте проигрывателя endo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>OpenZoom</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="openzoom-min.js"></script>
</head>
<body>
<h2>OpenZoom</h2>
<!-- Your high-resolution image -->
<img src="nano/02-50x279.jpg" width="500" height="279" openzoom:source="nano/image.dzi">
</body>
</html>

В этом случае нам потребуются уже два скрипта jquery.min.js и openzoom-min.js, но появится возможность подставить в виде стартовой миниатюры собственную картинку, возможно, слегка подретушированную для лучшего восприятия.

фото

Проект Zoomify коммерческий и закрытый. Можно купить программы для представления снимков с использованием технологии html 5 или flash.

Проигрыватель для flash zoomifyViewer.swf распространяется с минимальными ограничениями, в том числе и в составе пакета MagickTiler. Для его использования в html надо вставить ссылку только на этот файл. JS в данном случае не используется. Проигрыватель оказался более капризным и с некоторыми браузерами, в которых OpenZoomViewer прекрасно работал, zoomifyViewer не запустился.

<HTML>
<BODY>
<DIV ALIGN="center">
<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=0 BGCOLOR=#000000 WIDTH="550" ALIGN="CENTER">
<TR>
<TD>
<TABLE BORDER=0 WIDTH=100% BGCOLOR=#ffffff CELLSPACING=0 CELLPADDING=0>
<TR>
<TD>
<OBJECT CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" CODEBASE= "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" WIDTH="550" HEIGHT="250" ID="theMovie">
<PARAM NAME="FlashVars" VALUE="zoomifyImagePath=zoomify/zoom1">
<PARAM NAME="MENU" VALUE="FALSE">
<PARAM NAME="SRC" VALUE="zoomify/zoomifyViewer.swf">
<EMBED FlashVars="zoomifyImagePath=zoomify/zoom1" SRC="zoomify/zoomifyViewer.swf" MENU="false" PLUGINSPAGE= "http://www.macromedia.com/shockwave/download/index.cgi? P1_Prod_Version=ShockwaveFlash" WIDTH="550" HEIGHT="250" NAME="theMovie"></EMBED>
</OBJECT></TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=0 BGCOLOR=#FFFFFF WIDTH="550" ALIGN="CENTER">
<TR>
<TD align="Right">
</TD>
</TABLE>
</DIV>
</BODY>
</HTML>

Пример просмотра фотографии в ИК-диапазоне, реализованный этим методом.

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

Для демонстрации возможностей размещения на одной странице нескольких больших фотографий приведу еще два примера.

Панорама Москвы, снятая со смотровой площадки Воробьевых гор камерой Canon PowerShon 650 IS при фокусном расстоянии объектива равном 44 мм. При предельном уменьшении с использованием метода antialias картинка, содержащая много мелких деталей, сильно замыливается, но в остальных промежуточных масштабах она получается наиболее приемлемой. Если создавать уменьшенные варианты по методу bicubic, то картинка, на мой взгляд, получается излишне пестрой, с элементами муара.

Еще один случай, когда может понадобиться данный метод представления изображений, это съемка картин с возможностью детального изучения отдельных мазков кистью. Ниже приведена фотография пейзажа, написанного Михаилом Рундальцовым. Это, вероятно, первая столь подробная фотография его живописного творчества. В основном он известен как художник-гравер, создавший портреты членов императорской семьи, А. Ф. Керенского, В. И. Ленина.




Дополнительно

iXBT BRAND 2016

«iXBT Brand 2016» — Выбор читателей в номинации «Процессоры (CPU)»:
Подробнее с условиями участия в розыгрыше можно ознакомиться здесь. Текущие результаты опроса доступны тут.

Нашли ошибку на сайте? Выделите текст и нажмите Shift+Enter

Код для блога бета

Выделите HTML-код в поле, скопируйте его в буфер и вставьте в свой блог.