在小帆布上绘制的大图像变得模糊

时间:2013-08-30 07:20:38

标签: javascript css3 html5-canvas

在我的项目中,我有一个画布(200 * 150),我想画一个大小(800 * 600)的图像。结果是图像变得更蓝(不光滑和清晰),但如果我们将该图像放在 img 标签上,它看起来很好。那我们该怎么处理呢?感谢。

<img src="http://www.drivingkids.com/wp-content/uploads/2010/07/preschool-math-game-for-kids-math-racing-equatations.jpg"
width="200" heigh="150" />
<canvas id="my_canvas" width="200" height="150"></canvas>
<script type="text/javascript">
    window.onload = function () {
        var context = document.getElementById("my_canvas").getContext("2d");
        var image = new Image();
        image.src = "http://www.drivingkids.com/wp-content/uploads/2010/07/preschool-math-game-for-kids-math-racing-equatations.jpg";
        image.onload = function () {
            context.drawImage(image, 0, 0, context.canvas.width, context.canvas.height); //dx-30, GY-28, GW+50, GH+35
        }
    }
</script>

1 个答案:

答案 0 :(得分:2)

原因

浏览器可以根据当前情况确定质量或性能的优先级。

对于大多数页面,图像质量通常优先于性能。但是对于画布性能不如使用直接浏览器渲染和CSS那样好,因此使用画布进行插值可能会在质量之前优先考虑性能。取决于浏览器的实现。

解决方案

幸运的是,通过在两个(或更多)步骤中执行调整大小和插值,或者如果您愿意,可以通过一个中间步骤来分解负担。

中间步骤将首先将图像缩放50%到离屏画布。然后使用该画布绘制到最终大小。对于较大的图像,可能需要更多步骤。

由于获得新尺寸的操作总和(更简单地说:使用中间步骤x2进行插值,而不是插入x1更多),所以总和花费的时间大致相同,所以你不会注意到太多降低性能。

但最重要的是:结果会比只采取一步更好。

实施

这是您实现中间步骤的方法:

image.onload = function () {

     /// create an extra step for re-sizing image
     var tmpCanvas = document.createElement('canvas'),
         tmpContext = c.getContext('2d');

     /// set this canvas to 50% of image
     tmpCanvas.width = image.width * 0.5;
     tmpCanvas.height = image.height * 0.5;

     /// draw image step 1
     tmpContext.drawImage(image, 0, 0, image.width * 0.5, image.height * 0.5);

     /// draw image step 2
     context.drawImage(tmpCanvas, 0, 0, canvas.width, canvas.height);
}

演示(概念验证)

<强> ONLINE DEMO HERE

结果将是:

snapshot of result
左图:IMG元素。右图:画布两步(在Firefox中渲染)

正如您所看到的,图像和画布元素之间现在没有明显的区别。