简体   繁体   English

HTML5 Canvas中的超高分辨率图像

[英]Very High Resolution Images in HTML5 Canvas

At the end of this question is an SSCCE to display a 24000x12000 Miller projection of satellite imagery on an HTML5 canvas. 该问题的末尾是一个SSCCE,它将在HTML5画布上显示24000x12000 Miller卫星图像的投影。 It has a couple problems: 它有几个问题:

  1. Rather than showing the entire image in one screen as I desire only a small section of the upper left corner is displayed. 而不是像我希望的那样在一个屏幕上显示整个图像,只显示了左上角的一小部分。
  2. The image suffers from extreme pixellation that should not appear at the scale displayed because the image is very high resolution 图像遭受极端像素化,不应出现在所显示的比例尺上,因为图像分辨率很高

在此处输入图片说明

  • The image used is available at Wikimedia . 使用的图像可从Wikimedia获得 I renamed it "world.jpg". 我将其重命名为“ world.jpg”。
  • This is not a normal web application and the large image will not be downloaded during application execution so any advice to not require downloading such a large image is moot. 这不是正常的Web应用程序,并且在应用程序执行期间不会下载大图像,因此不建议下载不需要下载如此大图像的任何建议。
  • The application will dynamically zoom into various map areas, thus the large image size. 该应用程序将动态缩放到各个地图区域,因此图像较大。
  • In the real code I use an external stylesheet and javascript file. 在实际代码中,我使用了外部样式表和javascript文件。 I integrated them into the html solely for the SSCCE. 我仅将它们集成到SSCCE的html中。

This is the code. 这是代码。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>The Earth</title>
<script type="text/javascript">
function draw() {
   var canvas = document.getElementById("canvas");
   var ctx = canvas.getContext("2d");
   var map = new Image();
   map.src = "world.jpg";
   map.onload = function() {
      var width = window.innerWidth;
      var height = window.innerHeight;
      ctx.drawImage(map, 0, 0, width, height);
   };
}
</script>
<style>
html, body {
  width:  100%;
  height: 100%;
  margin: 0px;
}
#canvas {
   width: 100%;
   height: 100%;
   position: absolute;
   top: 0px;
   left: 0px;
   background-color: rgba(0, 0, 0, 0);
}
</style>
</head>
<body onload="draw();">
   <canvas id="canvas"></canvas>
</body>
</html>

Use the version of context.drawImage that clips and scales the original image: 使用用于裁剪和缩放原始图像的context.drawImage版本:

context.drawImage(
    sourceImage,
    clipSourceAtX, clipSourceAtY, sourceClipWidth, sourceClipHeight,
    canvasX, canvasY, canvasDrawWidth, canvasDrawHeight
)

For example, assume that you are focusing on coordinate [x==1000,y==500] on the image. 例如,假设您正在关注图像上的坐标[x == 1000,y == 500]。

To display the 640px x 512px portion of the image at [1000,500] you can use drawImage like this: 要以[1000,500]显示图像的640px x 512px部分,可以使用如下所示的drawImage:

context.drawImage(

    // use "sourceImage" 
    sourceImage

    // clip a 640x512 portion of the source image at left-top = [1000,500]
    sourceImage,1000,500,640,512,

    // draw the 640x512 clipped subimage at 0,0 on the canvas
    0,0,640,512            
);

A demo: http://jsfiddle.net/m1erickson/MtAEY/ 演示: http : //jsfiddle.net/m1erickson/MtAEY/

在此处输入图片说明

Here's the working javascript code, formatted nicely. 这是有效的javascript代码,格式正确。

function draw() {
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");
  var map = new Image();
  map.src = "world.jpg";
  map.onload = function() {
    var width = window.innerWidth;
    var height = window.innerHeight;
    canvas.width=width;
    canvas.height=height;
    var mapWidth=map.width;
    var mapHeight=map.height;
    var scale=scalePreserveAspectRatio(mapWidth,mapHeight,width,height);
    ctx.mozImageSmoothingEnabled = false;
    ctx.imageSmoothingEnabled = false;
    ctx.webkitImageSmoothingEnabled = false;
    ctx.drawImage(map, 0, 0, mapWidth, mapHeight, 0, 0, mapWidth*scale, mapHeight*scale);
  };
}
function scalePreserveAspectRatio(imgW,imgH,maxW,maxH){
  return(Math.min((maxW/imgW),(maxH/imgH)));
}

The key is the two lines 关键是两行

canvas.width=width;
canvas.height=height;

Simply setting these to 100% in CSS doesn't work, the 100% is apparently not 100% of the inner dimensions of the window as I assumed. 在CSS中将它们简单地设置为100%是行不通的,这100%显然不是我假设的窗口内部尺寸的100%。 Since these dimensions are dynamic they must be set via JS not CSS. 由于这些尺寸是动态的,因此必须通过JS而不是CSS进行设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM