阅读 176

canvas 绘制图片模糊问题解决

最近项目中用到一个显示文档的功能,上传文件后,后台处理成图片。前端把图片绘制到canvas上显示,但是效果却不太好,canvas里的文字看起来很模糊。先看下效果,如图1所示,截图均是在1920*1080分辨率的显示器上截取。

图1

图片中上半部分是canvas,下面是图片,图片分辨率是 2479*3508,图片显示宽度是800px。绘制方法

    <canvas id="canvas" width="800" height="400"></canvas>
    <img id="docImg" src="./doc3.jpg" alt="">
    <script>
        var canvas = document.querySelector('#canvas')
        var ctx = canvas.getContext('2d')
        var img = document.querySelector('#docImg')
        img.onload = function () {
            ctx.drawImage(img, 0, 0, 800, 1132)
            ctx.strokeStyle='#f00'
            ctx.strokeRect(0,0,400,50)
        }
    </script>
复制代码

可以看出来,canvas里的内容比图片模糊很多。因为图片本身宽是2479,只是样式宽度设置了800px,等于图片压缩显示了,所以清晰度没问题。 下面想怎么解决,首先想到高分屏的适配,尤其是Mac上。由图片的显示效果可想到,搞一个大点的canvas,再把canavs缩小显示,会不会跟图片一样效果呢。具体的缩放又有两种,一种是直接在canvas里用矩阵缩放,一种是使用样式的缩放

方法一 canvas 矩阵缩放

使用canvas 的 scale 缩放成0.5倍,然后绘制图片是,宽度是原来的2倍,代码如下

    <canvas id="canvas" width="800" height="400"></canvas>
    <img id="docImg" src="./doc3.jpg" alt="">
    <script>
        var canvas = document.querySelector('#canvas')
        var ctx = canvas.getContext('2d')
        var img = document.querySelector('#docImg')
        ctx.scale(0.5,0.5)
        img.onload = function () {
            ctx.drawImage(img, 0, 0, 800*2, 1132*2)
            ctx.strokeStyle='#f00'
            ctx.strokeRect(0,0,400,50)
        }
    </script>
复制代码

为了跟原来对比,画了一个红框矩形,宽400,高50。可以看出第二个里的矩形宽小了一半,由此可以看出来文档也是缩放过的。效果如图2 图2

但文字还是一样模糊,这方法一算是失败了。

方法二 样式缩放

canvas搞原来的2倍大,绘制时也绘制2倍,然后用css 里的 transform缩小canvas的显示。代码如下

    <canvas id="canvas" width="1600" height="800" style="transform:scale(0.5,0.5);transform-origin: 0 0;"></canvas>
    <img id="docImg" src="./doc3.jpg" alt="">
    <script>
        var canvas = document.querySelector('#canvas')
        var ctx = canvas.getContext('2d')
        var img = document.querySelector('#docImg')
        img.onload = function () {
            ctx.drawImage(img, 0, 0, 800*2, 1132*2)
            ctx.strokeStyle='#f00'
            ctx.strokeRect(0,0,400,50)
        }
    </script>
复制代码

注意canvas设置了width,height属性是原来2倍,不能使用css 里的宽高。看效果

图3

基本跟图片一样了,其中那个红色矩形能明显看出来变细了,所以显示效果更细腻,就解决了图片模糊的问题。 这里有一个附作用,canvas用transform scale缩放后,在DOM流中的位置还是原来的大小,所以要通过其他样式去处理下。我这里用了transform-origin缩放原点为左上角。下面的图片等其他DOM元素定位,使页面上不会留大片空白。

关于第二种方法,为什么不能用样式里的宽高,下一篇专门介绍一下,canvas里的变换。

文章分类
前端
文章标签