簡體   English   中英

如何使用openlayers在瀏覽器中顯示高分辨率圖像

[英]How to display high resolution image in browser using openlayers

我試圖在使用openlayers 5的瀏覽器中顯示高分辨率圖像。我找到了一個示例,該示例說明了如何使用zoomify創建圖像圖塊並使用openlayers貼圖進行渲染。 但是我無法將其用於自己的圖像。 我對此完全陌生。 我問的問題可能很瑣碎。 請忍受我的無知。

示例代碼 -這是來自openlayers網站的示例。 我正在嘗試對這張圖片做同樣的事情 高分辨率圖像 我嘗試用圖片網址替換zoomifyUrl和iipUrl,但是沒有用。

import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import Zoomify from 'ol/source/Zoomify.js';

var imgWidth = 799;
var imgHeight = 586;

var zoomifyUrl = 'https://live.staticflickr.com/8173/7993440342_5d9c68faec_c.jpg';
var iipUrl = 'https://live.staticflickr.com/8173/7993440342_5d9c68faec_c.jpg' + '&JTL={z},{tileIndex}';

var layer = new TileLayer({
  source: new Zoomify({
    url: zoomifyUrl,
    size: [imgWidth, imgHeight],
    crossOrigin: 'anonymous'
  })
});

var extent = [0, -imgHeight, imgWidth, 0];

var map = new Map({
  layers: [layer],
  target: 'map',
  view: new View({
    // adjust zoom levels to those provided by the source
    resolutions: layer.getSource().getTileGrid().getResolutions(),
    // constrain the center: center cannot be set outside this extent
    extent: extent
  })
});
map.getView().fit(extent);

var control = document.getElementById('zoomifyProtocol');
control.addEventListener('change', function(event) {
  var value = event.currentTarget.value;
  if (value === 'iip') {
    layer.setSource(new Zoomify({
      url: iipUrl,
      size: [imgWidth, imgHeight],
      crossOrigin: 'anonymous'
    }));
  } else if (value === 'zoomify') {
    layer.setSource(new Zoomify({
      url: zoomifyUrl,
      size: [imgWidth, imgHeight],
      crossOrigin: 'anonymous'
    }));
  }

});

我想在openseadragon網站上實現類似的演示。 更改上面的代碼后,我得到一個網格,其中重復了一部分圖像。 最終形象

要使用Zoomify,您需要一台支持作為圖塊的圖像的服務器。 您使用的網址是flickr上的靜態圖片,OpenLayers需要將其作為ImageStatic處理。 這是使用來自flickr的最高分辨率圖像的代碼

  var extent = [0, 0, 10000, 7328]; var resolutions = [64, 32, 16, 8, 4, 2, 1]; var layer = new ol.layer.Image({ source: new ol.source.ImageStatic({ url: 'https://live.staticflickr.com/8173/7993440342_6a1f281898_o_d.jpg', imageExtent: extent }) }); var map = new ol.Map({ layers: [layer], target: 'map', view: new ol.View({ // adjust zoom levels to those provided by the source resolutions: resolutions, // constrain the center: center cannot be set outside this extent extent: extent }) }); map.getView().fit(extent); 
 html, body, .map { margin: 0; padding: 0; width: 100%; height: 100%; } 
 <link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" /> <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script> <div id="map" class="map"></div> 

或者,您可以鏈接到OpenSeadragon使用的URL。 奇怪的是,縮放級別從8到14,其中第8級有一個圖塊,第14級有55 x 41的網格,其中最右邊一列的圖塊寬206px,底行的圖塊高41px。 可以使用Zoomify,但需要自定義圖塊網址功能才能將8疊加到OpenLayers期望的縮放級別。

  var imgWidth = 54*256 + 206; var imgHeight = 40*256 + 41; var zoomifyUrl = 'https://openseadragon.github.io/example-images/duomo/duomo_files/{z}/{x}_{y}.jpg'; var layer = new ol.layer.Tile({ source: new ol.source.Zoomify({ url: zoomifyUrl, size: [imgWidth, imgHeight], crossOrigin: 'anonymous' }) }); layer.getSource().setTileUrlFunction(function(tileCoord) { return zoomifyUrl.replace( '{z}', tileCoord[0]+8 ).replace( '{x}', tileCoord[1] ).replace( '{y}', -(tileCoord[2]+1) ); }); var extent = [0, -imgHeight, imgWidth, 0]; var map = new ol.Map({ layers: [layer], target: 'map', view: new ol.View({ // adjust zoom levels to those provided by the source resolutions: layer.getSource().getTileGrid().getResolutions(), // constrain the center: center cannot be set outside this extent extent: extent }) }); map.getView().fit(extent); 
 html, body, .map { margin: 0; padding: 0; width: 100%; height: 100%; } 
 <link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" /> <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script> <div id="map" class="map"></div> 

從該嘗試的結果來看,很明顯有些圖塊只有255px,而不是標准的256px,這導致在輸出上出現白線。 我添加了一個自定義圖塊加載功能,以將255px的寬度或高度拉伸到256(但不能在其右邊緣和下邊緣拉伸圖塊的寬度小於255px)。

  var imgWidth = 54*256 + 206; var imgHeight = 40*256 + 41; var zoomifyUrl = 'https://openseadragon.github.io/example-images/duomo/duomo_files/{z}/{x}_{y}.jpg'; var layer = new ol.layer.Tile({ source: new ol.source.Zoomify({ url: zoomifyUrl, size: [imgWidth, imgHeight], crossOrigin: 'anonymous' }) }); layer.getSource().setTileUrlFunction(function(tileCoord) { return zoomifyUrl.replace( '{z}', tileCoord[0]+8 ).replace( '{x}', tileCoord[1] ).replace( '{y}', -(tileCoord[2]+1) ); }); var tileSize = ol.size.toSize(layer.getSource().getTileGrid().getTileSize(0)); layer.getSource().setTileLoadFunction(function(imageTile, src) { var img = document.createElement('img'); img.onload = function() { var width = img.naturalWidth >= tileSize[0]-1 ? tileSize[0] : img.naturalWidth; var height = img.naturalHeight >= tileSize[1]-1 ? tileSize[1] : img.naturalHeight; var canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; var ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, width, height); imageTile.getImage().src = canvas.toDataURL(); }; img.crossOrigin = 'anonymous'; img.src = src; }); var extent = [0, -imgHeight, imgWidth, 0]; var map = new ol.Map({ layers: [layer], target: 'map', view: new ol.View({ // adjust zoom levels to those provided by the source resolutions: layer.getSource().getTileGrid().getResolutions(), // constrain the center: center cannot be set outside this extent extent: extent }) }); map.getView().fit(extent); 
 html, body, .map { margin: 0; padding: 0; width: 100%; height: 100%; } 
 <link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" /> <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script> <div id="map" class="map"></div> 

使用dzi XML解析器:

 var map = new ol.Map({ target: 'map', logo: false }); var layer = dzi.loadUrl( 'https://openseadragon.github.io/example-images/duomo/duomo.dzi', { attributions: 'Image &copy 2012, <a href="https://www.flickr.com/photos/projectese/" target="_blank">Dario Morelli</a>' } ); layer.on('change:source', function(evt) { map.setView( new ol.View({ resolutions: layer.getSource().getTileGrid().getResolutions(), extent: layer.getExtent() }) ); map.getView().fit(layer.getExtent(), { size: map.getSize() }); }); map.addLayer(layer); 
 html, body, .map { margin: 0; padding: 0; width: 100%; height: 100%; } 
 <link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" /> <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script> <script> dzi = function() { function loadUrl ( url, opt_options // attributions (defaults to undefined), crossOrigin (defaults to 'anonymous') ) { var options = opt_options || {}; var crossOrigin = options.crossOrigin === undefined ? 'anonymous' : options.crossOrigin; var layer = new ol.layer.Tile(); var last = url.lastIndexOf('.'); var path = url.slice(0, last); var xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.onload = function() { var parser = new DOMParser(); var xmlDoc = parser.parseFromString(xhr.responseText,'text/xml'); var elements = xmlDoc.getElementsByTagName('Image'); var tileSize = Number(elements[0].getAttribute('TileSize')); var format = elements[0].getAttribute('Format'); var width = Number(elements[0].getElementsByTagName('Size')[0].getAttribute('Width')); var height = Number(elements[0].getElementsByTagName('Size')[0].getAttribute('Height')); var url = path + '_files/{z}/{x}_{y}.' + format; var source = new ol.source.Zoomify({ attributions: options.attributions, url: url, size: [width, height], tileSize: tileSize, crossOrigin: crossOrigin }); var offset = Math.ceil(Math.log(tileSize)/Math.LN2); source.setTileUrlFunction(function(tileCoord) { return url.replace( '{z}', tileCoord[0] + offset ).replace( '{x}', tileCoord[1] ).replace( '{y}', -(tileCoord[2]+1) ); }); layer.setExtent([0, -height, width, 0]); layer.setSource(source); } xhr.send(); return layer; } return { "loadUrl" : loadUrl } } (); </script> <div id="map" class="map"></div> 

上面的答案有兩個問題:

  • 缺乏對zoomify中的deepzoom的支持
  • 瓷磚之間的白線。

我能夠弄清楚。 答案: 使用zoomify深度放大OpenLayers圖像

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM